K SUM问题

来源:互联网 发布:零基础学c语言 pdf 编辑:程序博客网 时间:2024/04/30 05:54

给定一个数组,找出两个或者几个数的加和为一个定值的问题,在笔试面试中也是经常考的,本文参考了其他博文结合了leetcode题目给出讲解。

1. Two Sum

题目:Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

(给定一个数组,找出两个数的加和为已知的一个定值。本题要求输出的是两个数在原数组中的下标而且要求index1<index2。

解题几种思路:

(1)直观想法双层for循环嵌套遍历数组,如果和为定值,则保存。此时时间复杂度为O(n^2)

(2)先给已知数组进行排序 O(nlogn),然后再给两个指针分别一头一尾进行查找O(n),判断其加和sum是否等于target。

若sum=target,则表明满足条件;若sum>target,说明值较大,指向较大一端要向下指,使其变小;若sum<target,说明值较小,指向较小一端要向下指,使其变大。总共时间复杂度还是为O(nlogn)。

代码:

class Solution {public:    vector<int> twoSum(vector<int>& nums, int target) {                vector<int> temp(nums);          vector<int> index;                int num1,num2;        sort(temp.begin(), temp.end());//排序                int sum;        int i=0;        int j=nums.size()-1;                while(i<j)        {            sum=temp[i]+temp[j];                        if(sum==target)//等于就表明找到            {                num1=temp[i];                num2=temp[j];                break;//因为本题是只存在一组解,若果有很多组解此处可以改成 先存储再i++; j--;            }                        if(sum>target)            {                j--;            }                        if(sum<target)            {                i++;            }        }               for(i=0;i<nums.size();i++)//找到对应的下标       {           if(num1==nums[i])              {                  index.push_back(i+1);                  continue;              }                         if(num2==nums[i])              index.push_back(i+1);       }                   if(index[0]>index[1])//按要求使index1<index2       {           swap(index[0],index[1]);       }              return index;    }};

2.Three Sum

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)
解题思路:

先固定一个值设为a,用总和减去这个值,就转化为求解两个数为固定和2Sum的问题,新的target为target-a。此时时间复杂为O(nlogn + n^2)=O(n^2)。

除此之外,这里这道题要求去重。

去重就在于和之前的解进行比较,但我们不需要比较所有的解,这里有一个技巧。

1. 如果num[i] = num[i - 1],说明刚才i-1时求的解在这次肯定也会求出一样的,所以不用重复判断,直接跳过不求;

2. 当sum == 0,我们保存了当前解以后,需要num[i]在解中的其他的2个数组合,这个时候,肯定是p往后或者q往前,如果++p,发

    现其实num[p] == num[p-1],说明这个解肯定和刚才重复了,再继续++p。同理,如果--q后发现num[q] == num[q+1],继续--q。

    这个去重操作主要针对这种有多个同值的数组,如:-3, 1,1,1, 2,2,3,4。

代码:

class Solution {public:    vector<vector<int>> threeSum(vector<int>& nums) {                vector<vector<int>> res;//存储结果                if(nums.size()<3)            return res;                sort(nums.begin(),nums.end());//先排序                for(int i=0; i<nums.size(); ++i)        {            if(i!=0 && nums[i]==nums[i-1])//去重                continue;                            int p=i+1;//p只要从i+1开始即可,若从头开始就会重复遍历            int q=nums.size()-1;                        int sum=0;                      while(p<q)            {                sum=nums[i]+nums[p]+nums[q];                              if(sum==0)                {                                    vector<int> line;                   line.push_back(nums[i]);                   line.push_back(nums[p]);                   line.push_back(nums[q]);                   sort(line.begin(),line.end());                                      res.push_back(line);                                      while(++p<q && nums[p]==nums[p-1]);//去重                                 while(--q>p && nums[q]==nums[q+1]); //去重            }                if(sum>0)                {                    q--;                }                             if(sum<0)                {                    p++;                }            }        }              return res;          }};




1 0
原创粉丝点击