【LeetCode】HOT 100(3)

题单介绍:

精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。

目录

题单介绍:

题目:15. 三数之和 - 力扣(Leetcode)

题目的接口:

解题思路:

代码:

过过过过啦!!!!

题目:22. 括号生成 - 力扣(Leetcode)

题目的接口:

解题思路:

代码:

过过过过啦!!!!

写在最后:


题目:15. 三数之和 - 力扣(Leetcode)

题目的接口:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {

    }
};

解题思路:

突然发现LeetCode更新了一个新功能,可以查看题目的提示,

放出来看一眼:

好吧,我英语不好,但是我大概可以猜出这个提示,

好像不是教我们题目的解题思路,而是教题目的优化思路,可恶。

具体思路是:

遍历数组确定区间:

 双指针找 == 0的三数之和,注意去重情况即可。

(如果有连续的相同数字需要去重操作)

代码入下:

代码:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        if(nums.size() < 3) return {}; //特殊情况

        vector<vector<int>> vv; 
        sort(nums.begin(), nums.end()); //排序

        for(int i = 0; i < nums.size(); i++) { //遍历
            if(nums[i] > 0) return vv; //如果i已经>0,三数之和不可能>0
            if(i > 0 && nums[i] == nums[i - 1]) continue; //去重

            //左右指针
            int left = i + 1; 
            int right = nums.size() - 1;

            while(left < right) {
                //>0 right--找小,<0 left++找大
                if(nums[left] + nums[right] + nums[i] > 0) right--;
                else if(nums[left] + nums[right] + nums[i] < 0) left++;
                else { //找到了
                    vv.push_back(vector<int>{nums[i], nums[left], nums[right]}); 
                    left++;
                    right--;
                    
                    //去重
                    while(left < right && nums[left] == nums[left - 1]) left++;
                    while(left < right && nums[right] == nums[right + 1]) right--;
                }
            }
        }
        return vv;
    }
};

过过过过啦!!!!

题目:22. 括号生成 - 力扣(Leetcode)

题目的接口:

class Solution {
public:
    vector<string> generateParenthesis(int n) {

    }
};

解题思路:

这道题目的方法有很多,我打算就说两种最好理解,最简单的

一种是dfs搜索+剪枝,

还有一种是根据题目的规律解题,

都采用的是递归,

先说第二种方法:

我们可以根据左括号数量一定是大于等于右括号数量这个规律进行判断:

代码如下:

class Solution {
public:
    vector<string> res;
    vector<string> generateParenthesis(int n) {
        if(n <= 0) return res;
        get_par("", n, n);
        return res;
    }
private:
    void get_par(const string& s, int left, int right) {
        if(left == 0 && right == 0) {
            res.push_back(s);
            return;
        }
        if(left == right) get_par(s + "(", left - 1, right); //如果括号数相等,只能入左括号
        else if(left < right) { //如果左括号<有括号数,入哪个都行
            if(left > 0) get_par(s + "(", left - 1, right); //当然,如果左括号入完了就不能入了
            get_par(s + ")", left, right - 1);
        }
    }
};

然后是第一种方法,

深搜遍历所有情况,

如果情况不符就返回(剪枝),

将符合的情况push进数组即可。

代码如下:

代码:

class Solution {
public:
    vector<string> res;
    vector<string> generateParenthesis(int n) {
        dfs("", n, n);
        return res;
    }
private:
    void dfs(const string& s, int left, int right) {
        if(left < 0 || left > right) return; //剪枝
        if(left == 0 && right == 0) { //符合的情况
            res.push_back(s);
            return;
        }
        //搜索所有情况
        dfs(s + "(", left - 1, right);
        dfs(s + ")", left, right - 1);
    }
};

过过过过啦!!!!

写在最后:

以上就是本篇文章的内容了,感谢你的阅读。

如果感到有所收获的话可以给博主点一个哦。

如果文章内容有遗漏或者错误的地方欢迎私信博主或者在评论区指出~

猜你喜欢

转载自blog.csdn.net/Locky136/article/details/130841871
今日推荐