leetcode-hot100

文章目录

哈希表

核心思想:哈希查找 O ( 1 ) O(1) O(1),使用set去重

例题

1. 两数之和

  • 只能使用O(n)的算法,因此不能考虑二分。暴力法是两次遍历,考虑仅使用一次遍历。
  • 解决方法:将遍历的元素存储在哈希表中,往已有哈希表中查找对应元素,可以实现一次遍历。

49. 字母异位词

  • 注意到所有字符串的顺序无关,所以对所有字符串进行排序 ,以排序后的值作为键建立映射关系。
    128.最长连续序列:``
  • 这题只能使用O(n)的算法。
  • 考虑只能遍历一次,将所有数组预先存储到哈希表中方便查找
  • 优化重复遍历:对于非首位元素,不进行查找

双指针:快慢指针

283.移动零

  • 这题就是典型的双指针例题,双指针具有明显的单调特性

11.盛最多水的容器

  • 假设h[i]<h[j]:说明i是瓶颈,必须移动i,如果i是单调递增,可以计算一次答案,否则可以继续移动i,直到h[i]>=h[j],此时拼接换到j。
cpp 复制代码
class Solution {
public:
    int maxArea(vector<int>& height) {
        int ans=INT_MIN;
        int i=0,j=height.size()-1;
        while(i<j){
            int w =j-i;
            int h=min(height[i],height[j]);
            ans=max(ans,w*h);
            while(height[i]<height[j]&&i<j){
                i++;
                int w =j-i;
                int h=min(height[i],height[j]);
                ans=max(ans,w*h);
            }
            while(height[i]>=height[j]&&i<j){
                j--;
                int w =j-i;
                int h=min(height[i],height[j]);
                ans=max(ans,w*h);
            }            
        }
        return ans;
    }
};

15.三数之和

  • 注意到这题的时间复杂度要求O(n^2)左右即可,因此可以考虑排序数组
  • 第一重循环固定i,第二重循环使用双指针优化。
  • 注意数组具有明显的单调性,可以使用双指针用来寻找答案。

排列问题去重if a[i]=a[i-1] then continue

  • i需要去重
cpp 复制代码
if(j>i+1&&nums[j]==nums[j-1]){
                    j++;
                    continue;
                }
  • j和k也需要进行去重
cpp 复制代码
                if(j>i+1&&nums[j]==nums[j-1]){
                    j++;
                    continue;
                }
                if(k<nums.size()-1&&nums[k]==nums[k+1]){
                    k--;
                    continue;
                }

42.接雨水

  • 暴力做法:对于当前台阶,选择左右两边最高的柱子,然后按照列的方式计算当前台阶的雨水量
  • 简单优化:加速寻找最大台阶的步数,使用单调容器获得比当前柱子大的最近一个元素所在的位置 。时间复杂度快一点,但是最坏仍然是平方
cpp 复制代码
class Solution {
public:
    typedef struct node{
        int idx,val;
        node(int x,int y):idx(x),val(y){};
    };
    int trap(vector<int>& height) {
        vector<int>left(height.size(),-1);
        vector<int>right(height.size(),-1);
        deque<node>q;
        for(int i=0;i<height.size();i++){
            while(q.size()&&q.back().val<=height[i]){
                q.pop_back();
            }
            if(q.size()){
                left[i]=q.back().idx;
            }
            q.push_back(node(i,height[i]));
        }
        q.clear();
        for(int i=height.size()-1;i>=0;i--){
            while(q.size()&&q.back().val<=height[i]){
                q.pop_back();
            }
            if(q.size()){
                right[i]=q.back().idx;
            }
            q.push_back(node(i,height[i]));
        }
        int res=0;
        for(int i=0;i<height.size();i++){
            int j=i,k=i;
            while(left[j]!=-1)j=left[j];
            while(right[k]!=-1)k=right[k];
            if(i==j||j==k)continue;
            int h = min(height[j],height[k])-height[i];
            res+=h;
        }
        return res;
    }
};
  • 优化思路2:按照行的形式问题,之前的元素递减时不需要计算,一旦出现递增的情况,就要横向计算雨水量 。发现可以使用单调栈来模拟这一个过程。
    一定要使用行的形式计算雨水!!!

双指针:滑动窗口

3.无重复字符的最长子串

  • 双指针:当出现重复就增加指针j,试图删去重复元素。

438.找到字符串中所有字母异位词

  • 异位词:位置不同,字符种类和数量一致。
  • 排序后可以作为键
  • 如果连续,子串可以共用一个hash数组 ;如果不连续的子串需要使用两个hash数组进行控制。判断是否是一个词可以直接暴力,复杂度取决于种类例如26个字母复杂度为 O ( 26 ) O(26) O(26)

子串

560.和为K 的子数组

  • 使用hash表加速查询,使用前缀和加速求和运算。

239.滑动窗口最大值

  • 单调队列模板题

76.最小覆盖子串

  • 子串的暴力比较算法:遍历哈希表中每一个种类;然后使用双指针即可。

  • 时间复杂度1e7,勉强能过

  • 不暴力比较的方法
    优化方法

相关推荐
qq_148115372 小时前
分布式系统容错设计
开发语言·c++·算法
m0_560396472 小时前
C++中的享元模式
开发语言·c++·算法
左左右右左右摇晃2 小时前
数据结构——数组
数据结构·笔记·算法
nainaire2 小时前
速通LeetCode hot100——(1~9 哈希,双指针,滑动窗口)
c++·笔记·算法·leetcode
2501_924952692 小时前
分布式缓存一致性
开发语言·c++·算法
studyForMokey2 小时前
【Android面试】窗口机制专题
android·面试·职场和发展
萍萍学习3 小时前
蓝桥杯JAVA-4
java·职场和发展·蓝桥杯
XiYang-DING3 小时前
【LeetCode】LCR 019. 验证回文串 II
算法·leetcode·职场和发展