LeetCode刷题之路(第四天)

公告:作者已将LeetCode题目的答案整理至GitHub上,希望大家多多star,目前只有一部分,会每天持续更新的~~
地址:https://github.com/ZLeopard/LeetCode

15. 三数之和

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

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

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

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

思路:先对数组进行从小到大排序,然后使用双指针从两边逼近,这样的话会使得其可以在O(n)的时间内完成索引。
C++版本:

class Solution {
public:
    vector<vector<int> > threeSum(vector<int> &num) {
           vector<vector<int> > ans;
           sort(num.begin(),num.end());
           for(int i=0;i+2<num.size();i++){
               int l=i+1,r=num.size()-1;
               while(l<r){
                  while(l < r && num[i] + num[l] + num[r] > 0) r--;
                    if(l==r) break; //注意判断下相等的时候break。
                  if(num[i] + num[l] + num[r]==0){
                    ans.push_back(vector<int> { num[i], num[l], num[r]});
                    while(l<r&&num[l+1]==num[l]) l++;
                  }
                  l++;
               }
               while(i+1 < num.size()&&num[i+1] == num[i]) i++;
           }
           return ans;
    }
};

16. 最接近的三数之和

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

思路:与15题类似,首先对数组进行正向排序,固定一个值从0到len-2开始遍历,另外两个值从剩余部分的两端开始遍历。
c++代码如下:

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        sort(nums.begin(), nums.end());
        int sum = 0;
        int result = nums[0] + nums[1] + nums[2];
        for(int i = 0;i < nums.size()-2; i++){
            int l = i+1, r = nums.size()-1;
            while(l < r){
                sum = nums[i] + nums[l] + nums[r];
                if(sum < target)
                    l++;
                else
                    r--;
                if(abs(sum - target) < abs(result - target))
                    result = sum;
            }
        }
        return result;
    }
};

18. 四数之和

给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

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

扫描二维码关注公众号,回复: 3300155 查看本文章

示例:
给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。

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

思路:首先对数组进行排序,然后去固定两个数,在数组中开始遍历,接着这个问题就转化为了一个两数之和的问题,还是原来的思路,使用两个指针从两边开始遍历,知道两个指针指向同一个位置。

class Solution {
public:
    vector<vector<int> > fourSum(vector<int> &nums, int target) {
        sort(nums.begin(), nums.end());
        int sum = 0, result = nums[0] + nums[1] + nums[2];
        vector< vector<int> > res;
        int n = nums.size();
        if(n < 4)
            return res;
        for(int i = 0;i < n-3;i++){
            for(int j = i+1;j < n;j++){
                int s = target - nums[i] - nums[j];   //变成两数之和的问题
                int l = j + 1, r = n - 1;
                while(l < r){
                    while(l < r && nums[l] + nums[r] > s) r--;
                    if(l== r) break;
                    if(nums[l] + nums[r] == s){
                        vector<int> temp = {nums[i], nums[j], nums[l], nums[r]};
                        res.push_back(temp);
                        while(l < r && nums[l] == nums[l+1])
                            l++;
                    }
                    l++;
                }
                while(j < n-1 && nums[j] == nums[j+1]) 
                    j++;
            }
            while(i < n-4 && nums[i] == nums[i+1])
                i++;
        }
        return res;
    }
};

17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

在这里插入图片描述

示例:

输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”]. 说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

思路:使用递归的思想,每个数字对应的字母依次遍历。使用递归的方法必须设置递归的条件。条件是combine的字符位置是其最后一个。

class Solution {
private:
    map<char, string> charmap= {{'2', "abc"}, {'3', "def"}, {'4', "ghi"}, {'5', "jkl"},
                            {'6', "mno"}, {'7', "pqrs"}, {'8', "tuv"}, {'9', "wxyz"}};
    vector<string> res;
    string temp;
public:
    void combine(string &digits, int start){
        if(start == digits.length()){    // 回溯法也就是递归的方法
            res.push_back(temp); return;
        }
        for(int i = 0; i < charmap[digits[start]].length();i++){
            temp += charmap[digits[start]][i];
            combine(digits, start+1);
            temp.pop_back();     // 把多余的那个值给去掉
        }
    }
    vector<string> letterCombinations(string digits) {
        if(digits == "")
            return res;
        combine(digits, 0);
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_41576121/article/details/82788982