代码题(55)— 两数之和、三数之和

1、1. 两数之和

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。数组是无序的,返回对应下标。

你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

  这道题好就好在最低位在链表的开头,所以可以在遍历链表的同时按从低到高的顺序直接相加。while 循环的条件两个链表中只要有一个不为空行,由于链表可能为空,所以在取当前结点值的时候,先判断一下,若为空则取0,否则取结点值。然后把两个结点值相加,同时还要加上进位 carry。然后更新 carry,直接 sum/10 即可,然后以 sum%10 为值建立一个新结点,连到 cur 后面,然后 cur 移动到下一个结点。之后再更新两个结点,若存在,则指向下一个位置。while 循环退出之后,最高位的进位问题要最后特殊处理一下,若 carry 为1,则再建一个值为1的结点,代码如下:

示例:

给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> res;
        if(nums.empty())
            return res;
        unordered_map<int, int> nums_map;
        for(int i=0;i<nums.size();++i){
            nums_map[nums[i]] = i;
        }
        for(int i=0;i<nums.size();++i){
            int diff = target - nums[i];
            if(nums_map.count(diff) && nums_map[diff] != i){
                res.push_back(i);
                res.push_back(nums_map[diff]);
                break;
            }
        }
        return res;
    }
}; 

2、15. 三数之和

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

  首先,两数和问题这样做。先对数组中的数进行排序,再设置两个指针,一个指向头,一个指向尾。判断两数和是否等于想要的数,如果是则在结果集添加这个数组;如果小了说明左边指针指向的数小了,因此左指针右移;反之如果大了则右指针左移。 
尝试把三数和问题转化为两数和问题:同样先对数组排序,设置三个指针p,q,r,p指针指向第一个数x,则q,r要指向数组中剩余数中的两个,并且指向的两数和为-x,从而转化为两数和问题。对p指向第一个数的情况分析完毕后,不可能再有满足题意且包含x的情况,于是p右移。这样一直分析到p指向数组中倒数第三个数的情况。注意跳过所有重复的情况。

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()); // 首先排序
        vector<int> temp(3);
        int len = nums.size();
        for(int i=0;i<len-2;++i) // 首先固定一个变量,把三数之和变为两数之和的问题。
        {
            temp[0] = nums[i];
            int sum = -nums[i];
            int j=i+1,k=len-1;
            while(j<k)
            {
                int curSum = nums[j]+nums[k];
                if(curSum == sum)
                {
                    temp[1] = nums[j++];
                    temp[2] = nums[k--];
                    res.push_back(temp);
                    while(j<k && nums[j]==nums[j-1]) // 去重操作
                        j++;
                    while(j<k && nums[k]==nums[k+1])
                        k--;
                }
                else if(curSum < sum)
                    j++;
                else
                    k--;
            }
            while(i < len-2 && nums[i+1] == nums[i]) // 对于固定的数也要去重
                i++;
        }
         return res;   
    }
};

 

posted @ 2018-08-26 21:59  深度机器学习  阅读(424)  评论(0编辑  收藏  举报