zoukankan      html  css  js  c++  java
  • 代码题(55)— 两数之和、三数之和

    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> m;
            for(int i=0;i<nums.size();++i)
                m[nums[i]]=i;
            for(int i=0;i<nums.size();++i)
            {
                int t = target-nums[i];
                if(m.count(t) && m[t] != i) //找到,并且不是之前的数
                {
                    res.push_back(i);
                    res.push_back(m[t]);
                    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;   
        }
    };
  • 相关阅读:
    gThumb 3.1.2 发布,支持 WebP 图像
    航空例行天气预报解析 metaf2xml
    Baruwa 1.1.2 发布,邮件监控系统
    Bisect 1.3 发布,Caml 代码覆盖测试
    MoonScript 0.2.2 发布,基于 Lua 的脚本语言
    Varnish 入门
    快速增量备份程序 DeltaCopy
    恢复模糊的图像 SmartDeblur
    Cairo 1.12.8 发布,向量图形会图库
    iText 5.3.4 发布,Java 的 PDF 开发包
  • 原文地址:https://www.cnblogs.com/eilearn/p/9539144.html
Copyright © 2011-2022 走看看