leetcode双指针合集
生活随笔
收集整理的這篇文章主要介紹了
leetcode双指针合集
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
27. 移除元素
class Solution { public:int removeElement(vector<int>& nums, int val) {/**思路:使用快慢指針,快指針正常往后移動,并將獲取的值給慢指針,但是當快指針所指向的值是val的時候慢指針便不再更新;**/ int slowIndex = 0;for(int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {if(nums[fastIndex] != val) {nums[slowIndex] = nums[fastIndex];slowIndex++;}}return slowIndex; } };344. 反轉字符串
class Solution { public:void reverseString(vector<char>& s) {for(int i = 0,j = s.size()-1; i < s.size()/2; i++,j--) {swap(s[i],s[j]);}} };劍指 Offer 05. 替換空格
class Solution { public:string replaceSpace(string s) {/**思路:1.雙指針(一個指針指向舊的字符串末尾ptr1,一個指針指向擴容后的字符串末尾ptr2)2.對原字符串的擴容,因為%20是占3個空格的,所以要在原來一個空格基礎上進行擴容3.當遇到不是空格的時候,兩個指針指向的字符就正常賦值,如果當ptr1指向空格的時候ptr2就前面的3個空格 填上%20*/int count = 0;//記錄空格數int oldSize = s.size();for(int i = 0; i < s.size(); i++) {if(s[i] == ' '){count++;}}s.resize(oldSize+2*count);int newSize = s.size();//i和j模擬指針for(int i = oldSize-1,j = newSize-1; i>=0; i--,j--) {if(s[i] == ' '){s[j] = '0';s[j-1] = '2';s[j-2] = '%';j = j-2;}else{s[j] = s[i];} }return s;} };151. 翻轉字符串里的單詞
class Solution { public:/**思路:1.去除空格(字符串前面的空格 字符串中間冗余的空格 字符串后面的空格)2.反轉字符串3.將每個單詞進行反轉**/void removespacing(string &s) {int slowIndex = 0,fastIndex = 0;//定義快慢指針(最終慢指針為去完冗余空格的字符串)//去除字符串前面的空格while(s[fastIndex] == ' '){fastIndex++;}for( ; fastIndex < s.size(); fastIndex++) {//去除冗余的空格if(fastIndex-1 > 0 &&s[fastIndex-1] == s[fastIndex] && s[fastIndex] == ' '){continue;}else {s[slowIndex] = s[fastIndex];slowIndex++;} }//去除末尾的空格(如果字符串的末尾有多個空格的話 上方只能處理到末尾只有一個空格)if(slowIndex-1 > 0 && s[slowIndex - 1] == ' '){s.resize(slowIndex-1);}else{s.resize(slowIndex);}}void reverseStr(string &s,int start,int end){for(int i = start,j = end; i < j; i++,j--) {swap(s[i],s[j]);}}string reverseWords(string s) {removespacing(s);reverseStr(s,0,s.size() - 1);for(int i = 0; i < s.size(); i++) {int j = i;//找到空格while(j < s.size() && s[j] != ' ') {j++;}reverseStr(s,i,j-1);//這里j-1是因為s[j]已經表示的是空格了i = j;}return s;} };206. 反轉鏈表
class Solution { public:ListNode* reverseList(ListNode* head) {ListNode* temp;//存放臨時結點ListNode* cur = head;ListNode* pre = NULL;while(cur) {temp = cur->next;cur->next = pre;//調轉指針pre = cur;//往后移動一個結點cur = temp;}return pre;//當cur指向5的時候 下一個就指向空 那么pre = cur 則就表示前指針表示指向的是5} };19. 刪除鏈表的倒數第 N 個結點
class Solution { public:ListNode* removeNthFromEnd(ListNode* head, int n) {/**思路:1.雙指針(慢指針p1,快指針p2)2.要刪除倒數第n個結點,也就是要正向刪除 第(總的節點數 - n)個結點 3.為了處理倒數問題,先讓p2往后移動n個結點,(這時候p2還剩下(總的節點數-n = sum)),那么此時p1和p2一塊移動,等到p2指向末尾的時候,p1也就指向要刪除的結點*/ListNode* fakeNode = new ListNode(0);fakeNode->next = head;ListNode* slowNode = fakeNode;//慢指針ListNode* fastNode = fakeNode;//快指針while(n-- && fastNode != NULL) {fastNode = fastNode->next;}fastNode = fastNode->next;//讓其再快一格是為了當快指針到末尾的時候,慢指針指向要刪除結點的//的前一個結點 while(fastNode != NULL){fastNode = fastNode->next;slowNode = slowNode->next;}slowNode->next = slowNode->next->next;return fakeNode->next;} };18. 四數之和
class Solution { public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int> >ans;vector<int> v;sort(nums.begin(),nums.end());for(int i = 0; i < nums.size(); i++) {if(i > 0 && nums[i-1] == nums[i]) {continue;}for(int j = i+1; j < nums.size(); j++) {if(j-1 > i &&nums[j-1] == nums[j]){//這里的j-1大于i主要考慮的是我們去重復的是從continue; //j開始指向的元素}int left = j+1;int right = nums.size() - 1;while(left < right) {if(nums[i]+nums[j] > target - (nums[left]+nums[right])) right--;else if(nums[i]+nums[j] < target - (nums[left]+nums[right])) left++;else {v.push_back(nums[i]);v.push_back(nums[j]);v.push_back(nums[left]);v.push_back(nums[right]);ans.push_back(v);//去重處理while(left < right && nums[right-1] == nums[right]) right--;while(left > right && nums[left+1] == nums[left]) left++;//換下一組right--;left++;v.clear();}} }}return ans;} };15. 三數之和
class Solution { public:vector<vector<int>> threeSum(vector<int>& nums) {/**思路:1.我們將所有元素進行升序處理(這樣處理的話,我們可以知道當前面的元素大于0的時候,那么便一定不會出現 a+b+c=0 2.這里我們設置三個指針(模擬的) 第一個指針(i)指向數組的第一個元素,第二個指針(left)指向數組的第二個元素,第三個指針(right)指向數組的最后的元素3.nums[i] + nums[left] + nums[right] > 0; right-- ,i和left不動nums[i] + nums[left] + nums[right] < 0; left++,i和right不動nums[i] + nums[left] + nums[right] = 0;left++,right--,i也移動一個單位當我們找到一組答案的時候,就要同時移動三個指針;因為當我們找到一組答案的時候,如果不移動i,只移動left和right,因為是升序的,那么的話nums[left] + nums[right] 只會更小與nums[i]相加也不會等于0;如果我們想要最終的和為0,那么的話nums[i] < 0,nums[left] < 0,nums[right] > 0,那么往后移動i,如果和為0的話 nums[left] + nums[right]的結果只會更小因此我們每確定一組答案的時候,需要同時移動left,right,i4.這里的去重,我們是當遇到相同的元素跳過它*/vector<vector<int> >ans;vector<int>v;sort(nums.begin(),nums.end());for(int i = 0; i < nums.size(); i++) {if(nums[i] > 0){//如果首元素大于0的話那么就不會有和為0了return ans;}if(i > 0 && nums[i] == nums[i-1]){continue;}int left = i+1;int right = nums.size() - 1;while(left < right) {int sum = nums[i] + nums[left] + nums[right];if(sum > 0) right--;else if(sum < 0) left++;else {v.push_back(nums[i]);v.push_back(nums[left]);v.push_back(nums[right]);ans.push_back(v);//去重處理(相鄰的元素出現了重復)while(left < right && nums[right-1] == nums[right]) right--;while(left < right && nums[left+1] == nums[left]) left++;//換下一組答案(上方的去重處理只是指針移動到最后一個重復的元素)right--;left++;v.clear();} }}return ans;} };142. 環形鏈表 II
class Solution { public:ListNode *detectCycle(ListNode *head) {/**思路:1.定義快慢指針(快指針一次移動一個節點,慢指針一次移動兩個結點)2.如果有環的話那么的話快慢指針一定會相遇(因為如果沒環的話快慢指針永遠不相遇)3.那么我們接下來就要確認出口在哪里,(根據以證明的結論,定義一個新的結點頭指針指向它,然后快指針和其一塊移動,當其相遇的時候,就是出口.**/ListNode* slowNode = head;ListNode* fastNode = head; //當fastNode->next != NULL的時候 是允許fastNode->next->next 為空的//如果沒有此條件的話,那么當指針指向最后一個結點的時候,fast->next 已經為空了,它便不能再指向空了//即fast->next->next (不能空指向空)while(fastNode != NULL && fastNode->next != NULL) {fastNode = fastNode->next->next;slowNode = slowNode->next;if(slowNode == fastNode){ListNode* temp1 = fastNode;ListNode* temp2 = head;while( temp1 != temp2) {temp1 = temp1->next;temp2 = temp2->next;}return temp1;} }return NULL;} };面試題 02.07. 鏈表相交
class Solution { public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {/**思路:1.雙指針(一個指針指向長鏈表,一個指針指向短鏈表)2.我們需要將兩個鏈表右對齊3.將其右對齊的目的是為了讓長鏈表的指針移動到和短鏈表指針相同的位置這樣就可以方便找到相同的指針(只要指針相同那么其接下來的數也相同)4.所以我們需要確定出長鏈表是誰 */ListNode* node1 = headA;//新定義一個結點方便操作,保存頭結點 ListNode* node2 = headB;int lenA = 0;int lenB = 0;while(node1 != NULL) {node1 = node1->next;lenA++;}while(node2 != NULL) {node2 = node2->next;lenB++;} node1 = headA;//上方已經將node1和node2移到最后了node2 = headB;//因為我們需要將長鏈表的指針進行移動 所以我們需要確定出長鏈表if(lenB > lenA){swap(lenA,lenB);swap(node1,node2);}int poor = lenA - lenB; //長鏈表比短鏈表多的長度while(poor--) {node1 = node1->next;} while(node1 != NULL) {if(node1 == node2) {return node1;}node1 = node1->next;node2 = node2->next;} return NULL;} };總結
以上是生活随笔為你收集整理的leetcode双指针合集的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: leetcode459. 重复的子字符串
- 下一篇: leetcode232. 用栈实现队列