Leetcode热题100

这篇具有很好参考价值的文章主要介绍了Leetcode热题100。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 两数之和

暴力:{i,j}直接返回vector<int>

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        for(int i=0;i<nums.size();i++){
            for(int j=i+1;j<nums.size();j++){
                if(nums[i]+nums[j]==target){
                    //大括号里面直接写元素->vector
                    return {i,j};
                }
            }
        }
        return {};
    }
};

哈希表:

map: 红黑树 具有自动排序的功能,是非严格的二叉搜索树。map内部的所有元素都是有序的,使用中序遍历可将键值按照从小到大遍历出来。插入的时间是O(logn),查询时间是O(logn)。可以支持所有类型的键值对
unordered_map: 哈希表(也叫散列表,通过关键码值映射到Hash表中一个位置来访问记录,查找的复杂度是O(1)。无序的(海量数据广泛应用)。插入的时间是O(logn),查询时间是O(1)。它的key只能是int、double等基本类型以及string,而不能是自己定义的结构体。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> hashtable;
        for (int i = 0; i < nums.size(); ++i) {
            auto it = hashtable.find(target - nums[i]);
            if (it != hashtable.end()) {
                return {it->second, i};
            }
            hashtable[nums[i]] = i;
        }
        return {};
    }
};

2. 字母异位词分组

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string,int> mp;
        vector<vector<string>> res;
        int num=-1;
        for(auto i:strs){
            string s=i;
            sort(s.begin(),s.end());
            if(mp.count(s)==0){
                mp[s]=++num;
                res.push_back({});
            } 
            res[mp[s]].push_back(i);
        }
        return res;
    }
};

官方:(还有一种是计每个字母出现的次数)

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string, vector<string>> mp;
        for (string& str: strs) {
            string key = str;
            sort(key.begin(), key.end());
            mp[key].emplace_back(str);
        }
        vector<vector<string>> ans;
        for (auto it = mp.begin(); it != mp.end(); ++it) {
            ans.emplace_back(it->second);
        }
        return ans;
    }
};

3. 最长连续序列

在未排序的数组中找到最长的连续序列。时间复杂度On,数字范围整个INT。

第一种:不断更新最长连续序列的左右两个端点 记录的最长连续序列值。

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_map<int,int> mp;
        int mx=0;
        for(auto i:nums){
            //未更新过的,已经在的话再更新会翻倍!
            if(mp.count(i)) continue;
            //找出当前数字左右两端的最长连续序列的长度
            int l=0;
            if(mp.count(i-1)) l=mp[i-1];
            int r=0;
            if(mp.count(i+1)) r=mp[i+1];
            //更新当前节点
            mp[i]=l+r+1;
            mx=max(mx,mp[i]);
            //更新当前节点所在的连续序列的左右两个端点的最长序列值,一定是最大的,因为在原来的基础上把左或右还有当前节点加上了!
            //只需要告知最左右两个就可以,因为之后出现的数一定是未出现过的,在这些区间外的点!!
            mp[i-l]=mp[i];
            mp[i+r]=mp[i];
        }
        return mx;
    }
};

第二种:回溯,记录每个点能找到的最右端点。初始化为i+1。

class Solution {
public:
    unordered_map<int,int> mp;
    int find(int x){
        if(!mp.count(x)) return x;
        else return mp[x]=find(mp[x]);
    }
    int longestConsecutive(vector<int>& nums) {
        for(auto i:nums) mp[i]=i+1;
        int mx=0;
        for(auto i:nums){
            mx=max(mx,find(i)-i);
        }
        return mx;
    }
};

第三种:集合 直接找

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_set<int> s;
        for(auto i:nums){
            s.insert(i);
        }
        int mx=0,now=0,cnt=0;
        for(auto i:s){
            if(!s.count(i-1)){
                now=i;cnt=1;
                while(s.count(now+1)){
                    now++;
                    cnt++;
                }
            }
            mx=max(mx,cnt);
        }
        return mx;
    }
};

4. 移动零

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int i=0,j=0,cnt=0;
        for(i=0;i<nums.size();i++){
            if(nums[i]!=0){
                nums[j++]=nums[i];
            }
            else{
                cnt++;
            }
        }
        while(cnt--){
            nums[j++]=0;
        }
    }
};

5. 盛最多水的容器

双指针:分别指向最左和最右,尽量保留 越靠近边上的 并且 高的

即无论我们怎么移动右指针,得到的容器的容量都小于移动前容器的容量。也就是说,这个左指针对应的数不会作为容器的边界了,那么我们就可以丢弃这个位置,将左指针向右移动一个位置,此时新的左指针于原先的右指针之间的左右位置,才可能会作为容器的边界。

class Solution {
public:
    int maxArea(vector<int>& height) {
        int i=0,j=height.size()-1,mx=0,now=0;
        while(i<j){
            now=(j-i)*min(height[i],height[j]);
            mx=max(mx,now);
            if(height[i]<height[j]){
                i++; 
            }
            else{
                j--;
            }
        }
        return mx;
    }
};

6. 三数之和

如果我们固定了前两重循环枚举到的元素 a 和 b,那么只有唯一的 c 满足a+b+c=0。枚举一个元素 b′ 时,由于 b′>b,那么满足 a+b′+c′=0 的 c' 一定有 c′<c,即 c′在数组中一定出现在 c 的左侧。也就是说,我们可以从小到大枚举b,同时从大到小枚举 c,即第二重循环和第三重循环实际上是并列的关系。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int len=nums.size();
        int k=len-1;
        vector<vector<int>> res;
        for(int i=0;i<len;i++){
            if(i==0||nums[i-1]!=nums[i]){
                k=len-1;
                for(int j=i+1;j<len;j++){
                    if(j==i+1||nums[j-1]!=nums[j]){
                        while(k>j+1&&(nums[i]+nums[j]+nums[k])>0){
                            k--;
                        }
                        if(k>j&&(nums[i]+nums[j]+nums[k])==0){
                                res.push_back({nums[i],nums[j],nums[k]});
                        }
                        //cout<<nums[i]<<" "<<nums[j]<<" "<<nums[k]<<endl;
                    }
                }
            }
        }
        return res;
    }
};

7. 接雨水

计算当前位置能接的雨水,左右两边最高的 较小值 就是能到达的最高。

class Solution {
public:
    int trap(vector<int>& height) {
        int len=height.size();
        int left[200005],right[200005];
        left[0]=height[0];
        for(int i=1;i<height.size();i++){
            left[i]=max(left[i-1],height[i]);
        }
        right[height.size()-1]=height[height.size()-1];
        for(int j=height.size()-2;j>=0;j--){
            right[j]=max(right[j+1],height[j]);
        }
        int sum=0;
        for(int i=0;i<height.size();i++){
            sum+=min(left[i],right[i])-height[i];
        }
        return sum;
    }
};

其实用两个常量记录就可以,不需要开数组文章来源地址https://www.toymoban.com/news/detail-633134.html

到了这里,关于Leetcode热题100的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【算法与数据结构】62、LeetCode不同路径

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :机器人只能向下或者向右移动,那么到达(i,j)位置的路径和(i-1,j)以及(i,j-1)有关。那么我们就得到的动态规划的表达式 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d p [ i ] [ j − 1 ] dp[i][

    2024年01月18日
    浏览(65)
  • 【算法与数据结构】343、LeetCode整数拆分

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :博主做这道题的时候一直在思考,如何找到 k k k 个正整数, k k k 究竟为多少合适。从数学的逻辑上来说,将 n n n 均分为 k k k 个数之后, k k k 个数的乘积为最大(类似于相同周长

    2024年01月17日
    浏览(51)
  • 数据结构算法leetcode刷题练习(1)

    给定一个三角形 triangle ,找出自顶向下的最小路径和。 每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标

    2023年04月24日
    浏览(50)
  • 【python与数据结构】(leetcode算法预备知识)

    笔记为自我总结整理的学习笔记,若有错误欢迎指出哟~ 1.数字类型: 整数(int):表示整数值,例如 1、-5、100。 浮点数(float):表示带有小数部分的数字,例如 3.14、-0.5、2.0。 复数(complex):表示实部和虚部的复数,例如 2+3j。 2.布尔类型(bool): 表示真(True)或假(

    2024年02月08日
    浏览(38)
  • 【算法与数据结构】377、LeetCode组合总和 Ⅳ

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :本题明面上说是组合,实际上指的是排列。动态规划排列组合背包问题需要考虑遍历顺序。 d p [ i ] dp[i] d p [ i ] 指的是nums数组中总和为target的元素排列的个数。 d p [ i ] dp[i] d p [

    2024年01月23日
    浏览(40)
  • 【算法与数据结构】232、LeetCode用栈实现队列

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :这道题要求我们用栈模拟队列(工作上一定没人这么搞)。程序当中,push函数很好解决,直接将元素push进输入栈当中。pop函数需要实现队列先进先出的操作,而栈是先进后出。只

    2024年02月12日
    浏览(43)
  • 【算法与数据结构】226、LeetCode翻转二叉树

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :这道题的思路很简单,本质上就是遍历每一个节点,然后交换左右节点。我们可以用前中后遍历或者是层次遍历法来做,参考这两篇文章,【算法与数据结构】144、94、145LeetCode二

    2024年02月16日
    浏览(40)
  • 【算法与数据结构】28、LeetCode实现strStr函数

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :首先判断字符串是否合法,然后利用for循环,取出子字符串利用compare函数进行比较。    程序如下 : 复杂度分析: 时间复杂度: O ( n ∗ m ) O(n * m) O ( n ∗ m ) ,假设haystack的长

    2024年02月12日
    浏览(45)
  • 【算法与数据结构】654、LeetCode最大二叉树

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :【算法与数据结构】106、LeetCode从中序与后序遍历序列构造二叉树这两道题有些类似,相关代码可以互相参考,本题明示了要用递归来做,那么递归三要素不可缺少: 输入参数和返

    2024年02月09日
    浏览(44)
  • 【算法与数据结构】518、LeetCode零钱兑换 II

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :本题的硬币是无数的,因此本题可以抽象成一个完全背包问题。完全背包和01背包的不同之处在于完全背包式从前往后遍历的。在本题的完全背包问题中,amount代表背包的最大重量

    2024年01月23日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包