当前位置: 代码迷 >> 综合 >> LeetCode 之双指针 two pointers
  详细解决方案

LeetCode 之双指针 two pointers

热度:21   发布时间:2024-01-04 07:44:10.0

1. 3Sum

Given an array S of n integers, are there elements abc in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

  • Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
  • The solution set must not contain duplicate triplets.

    For example, given array S = {-1 0 1 2 -1 -4},A solution set is:(-1, 0, 1)(-1, -1, 2)
two pointer scan

遍历数组,双指针维护一个区间进行加和比较。

vector<vector<int> > threeSum(vector<int> &num) {vector<vector<int>> result;sort(num.begin(),num.end());for(int i=0; i<num.size(); i++){int target = 0-num[i];int start = i+1;int end = num.size()-1;while(start<end){if(num[start]+ num[end] == target){vector<int> solution;solution.push_back(num[i]);solution.push_back(num[start]);solution.push_back(num[end]);result.push_back(solution);start++, end--;while(start<end && num[start] == num[start-1]) start++;while(start<end && num[end] == num[end+1]) end--;}else if(num[start] + num[end] >target)end--;elsestart++;}while(i<num.size() && num[i] == num[i+1]) i++;}return result;
}
其中18,19行 去除前后的重复 比如[-2,-2,-2,0,2,3,4,4,4]

26行去除遍历时的重复 比如[2,2,3,3,5]

2. 3Sum Closet

Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

    For example, given array S = {-1 2 1 -4}, and target = 1.The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

与3Sum 类似,需要加一个记录最小距离的变量

int threeSumClosest(vector<int> &num, int target) {int result;vector<int> solution;sort(num.begin(), num.end());int minD = INT_MAX;for(int i=0; i<num.size()-2;i++){int start = i+1;int end = num.size()-1;while(start < end){int sum = num[i]+num[start]+num[end];if(sum == target){minD = 0;result = sum;return result;}else if(sum<target){if(target-sum < minD){minD = target-sum;result = sum;}start++;}else{if(sum-target < minD){minD = sum-target;result = sum;}end--;}}while(i<num.size() && num[i] == num[i+1]) i++;}return result;
}

3. 4Sum

Given an array S of n integers, are there elements abc, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note:

  • Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
  • The solution set must not contain duplicate quadruplets.

    For example, given array S = {1 0 -1 0 -2 2}, and target = 0.A solution set is:(-1,  0, 0, 1)(-2, -1, 1, 2)(-2,  0, 0, 2)

上述问题其实可以归纳为K sum问题,解题思路都比较相似。

都是要求, N个数字中,找出k个数字之和 == target (去重复)

解法:

排序,头尾两指针扫描找到相应的求和

3sum 可以化成 2sum, 4sum 可以化成3sum

比如:

排好序后数字为a b c d e f g h

先枚举a, 然后再b--h中查询

再枚举b 在c-h中查询

以此类推

这里有一篇博文总结的很好,来自烟客旅人

http://tech-wonderland.net/blog/summary-of-ksum-problems.html


vector<vector<int> > fourSum(vector<int> &num, int target) {vector<vector<int>> result;sort(num.begin(), num.end());for(int i=0; i<num.size();i++){int target1 = target- num[i];for(int j=i+1; j<num.size();j++){int target2 = target1-num[j];int start = j+1;int end = num.size()-1;while(start<end){if(num[start]+num[end]==target2){vector<int> solution;solution.push_back(num[i]);solution.push_back(num[j]);solution.push_back(num[start]);solution.push_back(num[end]);result.push_back(solution);start++, end--;while(start<end && num[start] == num[start-1]) start++;while(start<end && num[end] == num[end+1]) end--;}else if(num[start] + num[end] >target2)end--;elsestart++;}while(j<num.size() && num[j] == num[j+1]) j++;}while(i<num.size() && num[i] == num[i+1]) i++;}return result;
}

4.Add Binary

Given two binary strings, return their sum (also a binary string).

For example,
a = "11"
b = "1"
Return "100".

实现题, 双指针操作,

string addBinary(string a, string b) {string result;reverse(a.begin(),a.end());reverse(b.begin(),b.end());int maxL = a.size()>b.size() ? a.size() : b.size();int carry = 0;for(int i=0; i<maxL; i++){int la = i<a.size()? a[i]-'0':0;int lb = i<b.size()? b[i]-'0':0;int sum = (la+lb+carry)%2;carry = (la+lb+carry)/2;result.insert(result.begin(),sum+'0');}if(carry == 1)result.insert(result.begin(),'1');return result;
}

5. Add two numbers

You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8


和 add binary 类似,指针操作不同

v1

ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {int carry = 0;ListNode *result = new ListNode(-1);ListNode *head = result;ListNode *p1 = l1;ListNode *p2 = l2;while(p1!=NULL && p2!=NULL){int sum = (p1->val+p2->val+carry)%10;carry = (p1->val+p2->val+carry)/10;ListNode *didgt = new ListNode(sum);head->next = didgt;head = head->next;p1 = p1->next, p2 = p2->next;}while(p1!=NULL){int sum = (p1->val+carry)%10;carry = (p1->val+carry)/10;ListNode *didgt = new ListNode(sum);head->next = didgt;head = head->next;p1 = p1->next;}while(p2!=NULL){int sum = (p2->val+carry)%10;carry = (p2->val+carry)/10;ListNode *didgt = new ListNode(sum);head->next = didgt;head = head->next;p2 = p2->next;}if(carry!=0){ListNode *didgt = new ListNode(carry);head->next = didgt;}return result->next;
}


v2

ListNode *addTwoNumbersS2(ListNode *l1, ListNode *l2) {int carry = 0;ListNode *result = new ListNode(-1);ListNode *head = result;ListNode *p1 = l1;ListNode *p2 = l2;while(p1!=NULL || p2!=NULL){int av = p1 !=NULL? p1->val :0;int bv = p2 !=NULL? p2->val :0;int sum = (av+bv+carry)%10;carry = (av+bv+carry)/10;ListNode *didgt = new ListNode(sum);head->next = didgt;head = head->next;p1 = p1 !=NULL? p1->next:NULL;p2 = p2 !=NULL? p2->next:NULL;}if(carry!=0){ListNode *didgt = new ListNode(carry);head->next = didgt;}head = result->next;delete result;return head;
}

6.Remove Element

Given an array and a value, remove all instances of that value in place and return the new length.

The order of elements can be changed. It doesn't matter what you leave beyond the new length.

int removeElement(int A[], int n, int elem) {int cur =0;for(int i=0;i<n;i++){if(A[i]==elem)continue;A[cur] = A[i];cur++;}return cur;
}



未完待续