HOT 100(21~40)【LeetCode】3

简介: HOT 100(21~40)【LeetCode】3

75. 颜色分类【中等】

75.颜色分类

中等

1.6K

相关企业

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。


我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。


必须在不使用库内置的 sort 函数的情况下解决这个问题。

示例 1:
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
示例 2:
输入:nums = [2,0,1]
输出:[0,1,2]

提示:

n == nums.length

1 <= n <= 300

nums[i] 为 0、1 或 2

进阶:

你能想出一个仅使用常数空间的一趟扫描算法吗?
排序

class Solution {
    public void sortColors(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums.length-1-i; j++) {
                if (nums[j]>nums[j+1]){
                    swap(nums,j,j+1);
                }
            }
        }
    }
     public static void swap(int[] nums,int i,int j){
        int temp=nums[i];
        nums[i]=nums[j];
        nums[j]=temp;
    }
}

76. 最小覆盖子串【困难】

76.最小覆盖子串

困难

2.6K

相关企业

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。


注意:


对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。

如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例 1:
输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A'、'B' 和 'C'。
示例 2:
输入:s = "a", t = "a"
输出:"a"
解释:整个字符串 s 是最小覆盖子串。
示例 3:
输入: s = "a", t = "aa"
输出: ""
解释: t 中两个字符 'a' 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。

提示:

m == s.length

n == t.length

1 <= m, n <= 105

s 和 t 由英文字母组成

进阶:你能设计一个在 o(m+n) 时间内解决此问题的算法吗?
参考

滑动窗口

class Solution {
    Map<Character,Integer> ori=new HashMap<>();//t的字母统计
    Map<Character,Integer> cnt=new HashMap<>();//窗口中的字母统计
    public String minWindow(String s, String t) {
        //统计t的字母
        int tLen=t.length();
        for(int i=0;i<tLen;i++){
            char c=t.charAt(i);
            ori.put(c,ori.getOrDefault(c,0)+1);
        }
        //窗口
        int l=0,r=-1;
        int len=Integer.MAX_VALUE,ansL=-1,ansR=-1;
        int sLen=s.length();
        //滑动
        while(r<sLen){
            ++r;
            if(r<sLen&&ori.containsKey(s.charAt(r))){
                cnt.put(s.charAt(r),cnt.getOrDefault(s.charAt(r),0)+1);
            }
            //左移缩小窗口
            while(check()&&l<=r){
                if(r-l+1<len){
                    len=r-l+1;
                    ansL=l;
                    ansR=l+len;
                }
                if(ori.containsKey(s.charAt(l))){
                    cnt.put(s.charAt(l),cnt.getOrDefault(s.charAt(l),0)-1);
                }
                ++l;
            }
        }
        return ansL==-1?"":s.substring(ansL,ansR);
    }
    //检查是否符合覆盖条件
    public boolean check(){
        Iterator iter=ori.entrySet().iterator();
        while(iter.hasNext()){
            Map.Entry entry=(Map.Entry) iter.next();
            Character key=(Character) entry.getKey();
            Integer val=(Integer) entry.getValue();
            if(cnt.getOrDefault(key,0)<val){
                return false;
            }
        }
        return true;
    }
}

78. 子集【中等】

78.子集

中等

2.1K

相关企业

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例 1:
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入:nums = [0]
输出:[[],[0]]

提示:

1 <= nums.length <= 10

-10 <= nums[i] <= 10

nums 中的所有元素 互不相同

参考

回溯

class Solution {
    List<Integer> t=new ArrayList<>();
    List<List<Integer>> ans=new ArrayList<List<Integer>>();
    //回溯
    public List<List<Integer>> subsets(int[] nums) {
        dfs(0,nums);
        return ans;
    }
    public void dfs(int cur, int[] nums) {
        if(cur==nums.length){
            ans.add(new ArrayList<Integer>(t));
            return;
        }
        t.add(nums[cur]);
        dfs(cur+1,nums);
        t.remove(t.size()-1);
        dfs(cur+1,nums);
    }
}

79. 单词搜索【中等】

79.单词搜索

中等

1.6K

相关企业

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。


单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例 1:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
示例 2:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出:true
示例 3:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出:false

提示:


m == board.length

n = board[i].length

1 <= m, n <= 6

1 <= word.length <= 15

board 和 word 仅由大小写英文字母组成


进阶:你可以使用搜索剪枝的技术来优化解决方案,使其在 board 更大的情况下可以更快解决问题?

官方

回溯

class Solution {
    public boolean exist(char[][] board, String word) {
        int h = board.length, w = board[0].length;
        boolean[][] visited = new boolean[h][w];
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                boolean flag = check(board, visited, i, j, word, 0);
                if (flag) {
                    return true;
                }
            }
        }
        return false;
    }
    public boolean check(char[][] board, boolean[][] visited, int i, int j, String s, int k) {
        if (board[i][j] != s.charAt(k)) {
            return false;
        } else if (k == s.length() - 1) {
            return true;
        }
        visited[i][j] = true;
        int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
        boolean result = false;
        for (int[] dir : directions) {
            int newi = i + dir[0], newj = j + dir[1];
            if (newi >= 0 && newi < board.length && newj >= 0 && newj < board[0].length) {
                if (!visited[newi][newj]) {
                    boolean flag = check(board, visited, newi, newj, s, k + 1);
                    if (flag) {
                        result = true;
                        break;
                    }
                }
            }
        }
        visited[i][j] = false;
        return result;
    }
}

84. 柱状图中最大的矩形【困难】

84.柱状图中最大的矩形

困难

2.5K

相关企业

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例 1:
输入:heights = [2,1,5,6,2,3]
输出:10
解释:最大的矩形为图中红色区域,面积为 10
示例 2:
输入: heights = [2,4]
输出: 4

提示:

1 <= heights.length <=105

0 <= heights[i] <= 104

参考

class Solution {
    public int largestRectangleArea(int[] heights) {
        int len=heights.length;
        if(len==0){
            return 0;
        }else if(len==1){
            return heights[0];
        }
        int area = 0;
        Deque<Integer> stack=new ArrayDeque<>();
        for(int i=0;i<len;i++){
            //如果当前栈顶高度大于遍历到的高度,右边较低了到右边界,从左扫弾栈
            while(!stack.isEmpty()&&heights[stack.peekLast()]>heights[i]){
                //栈顶的高度
                int height=heights[stack.removeLast()];
                //栈顶与新栈顶高度一样弹出即可
                while(!stack.isEmpty()&&heights[stack.peekLast()]==height){
                    stack.removeLast();
                }
                int width;
                //如果刚好为空 即左边界在当前遍历
                if(stack.isEmpty()){
                    width=i;
                }else{//否则,左边界在新栈顶
                    width=i-stack.peekLast()-1;
                }
                area=Math.max(area,width*height);
            }
            //当前栈顶高度小于遍历到的高度,压栈
            stack.addLast(i);
        }
        //如果栈中还有元素,就是右边界在最右边
        while(!stack.isEmpty()){
            //栈顶的高度
            int height=heights[stack.removeLast()];
            //栈顶与新栈顶高度一样弹出即可
            while(!stack.isEmpty()&&heights[stack.peekLast()]==height){
                stack.removeLast();
            }
            int width;
            //如果刚好为空 即左边界在最左边
            if(stack.isEmpty()){
                width=len;
            }else{//否则,左边界在新栈顶
                width=len-stack.peekLast()-1;
            }
            area=Math.max(area,width*height);
        }
        return area;
    }
}

参考

class Solution {
    public int largestRectangleArea(int[] heights) {
        int len=heights.length;
        if(len==0){
            return 0;
        }else if(len==1){
            return heights[0];
        }
        int area = 0;
        //增加哨兵减少判断
        //左哨兵 0 heights 右哨兵 0
        int[] newHeights=new int[len+2];
        for(int i=0;i<len;i++){
             newHeights[i+1]=heights[i];
        }
        len+=2;
        heights=newHeights;
        Deque<Integer> stack=new ArrayDeque<>();
        stack.addLast(0);
        for(int i=1;i<len;i++){
            //如果当前栈顶高度大于遍历到的高度,右边较低了到右边界,从左扫弾栈
            while(heights[stack.peekLast()]>heights[i]){
                //栈顶的高度
                int height=heights[stack.removeLast()];
                //栈顶与新栈顶高度一样弹出即可
                //不保留
                int width=i-stack.peekLast()-1;
                area=Math.max(area,width*height);
            }
            //当前栈顶高度小于遍历到的高度,压栈
            stack.addLast(i);
        }
       return area;
    }
}

85. 最大矩形【困难】

85.最大矩形

困难

1.5K

相关企业

给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例 1:
输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出:6
解释:最大矩形如上图所示。
示例 2:
输入:matrix = []
输出:0
示例 3:
输入:matrix = [["0"]]
输出:0
示例 4:
输入:matrix = [["1"]]
输出:1
示例 5:
输入:matrix = [["0","0"]]
输出:0

提示:

rows == matrix.length

cols == matrix[0].length

1 <= row, cols <= 200

matrix[i][j] 为 ‘0’ 或 ‘1’

参考

class Solution {
    public int maximalRectangle(char[][] matrix) {
        int m=matrix.length;
        if(m==0){
            return 0;
        }
        int n=matrix[0].length;
        //存储左边连续的1的数量
        int [][] left=new int[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]=='1'){
                    left[i][j]=(j==0?0:left[i][j-1])+1;
                }
            }
        }
        int ret=0;
        //遍历作为矩形右下角
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]=='0'){
                    continue;
                }
                int width=left[i][j];
                int area=width;
                //往上查找
                for(int k=i-1;k>=0;k--){
                    //取得最小宽度
                    width=Math.min(width,left[k][j]);
                    //计算面积
                    area=Math.max(area,(i-k+1)*width);
                }
                ret=Math.max(ret,area);
            }
        }
        return ret;                   
    }
}

参考

class Solution {
    public int maximalRectangle(char[][] matrix) {
        int m = matrix.length;
        if (m == 0) {
            return 0;
        }
        int n = matrix[0].length;
        //存储左边连续的1的数量
        int[][] left = new int[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == '1') {
                    left[i][j] = (j == 0 ? 0 : left[i][j - 1]) + 1;
                }
            }
        }
        int ret = 0;
        //对于每一列,使用基于柱状图的方法
        for (int j = 0; j < n; j++) {
            int[] up = new int[m];//上
            int[] down = new int[m];//下
            Deque<Integer> stack = new LinkedList<Integer>();
            //赋值up
            for (int i = 0; i < m; i++) {
                //如果栈顶宽度大于遍历的 弾栈
                while (!stack.isEmpty() && left[stack.peek()][j] >= left[i][j]) {
                    stack.pop();
                }
                //赋值
                up[i] = stack.isEmpty() ? -1 : stack.peek();
                //否则压栈
                stack.push(i);
            }
            stack.clear();
            //复制down
            for (int i = m - 1; i >= 0; i--) {
                while (!stack.isEmpty() && left[stack.peek()][j] >= left[i][j]) {
                    stack.pop();
                }
                down[i] = stack.isEmpty() ? m : stack.peek();
                stack.push(i);
            }
            //计算面积
            for (int i = 0; i < m; i++) {
                int height = down[i] - up[i] - 1;
                int area = height * left[i][j];
                ret = Math.max(ret, area);
            }
        }
        return ret;
    }
}
相关文章
|
缓存 调度
HOT 100(导航)【LeetCode】
HOT 100(导航)【LeetCode】
79 0
|
调度
HOT 100(81~100)【LeetCode】4
HOT 100(81~100)【LeetCode】4
41 0
HOT 100(81~100)【LeetCode】3
HOT 100(81~100)【LeetCode】3
37 0
|
人工智能 BI 索引
HOT 100(81~100)【LeetCode】2
HOT 100(81~100)【LeetCode】2
50 0
|
算法 C++
HOT 100(81~100)【LeetCode】1
HOT 100(81~100)【LeetCode】1
50 0
|
缓存 Java 测试技术
HOT 100(41~60)【LeetCode】3
HOT 100(41~60)【LeetCode】3
39 0
|
存储 人工智能 算法
HOT 100(61~80)【LeetCode】1
HOT 100(61~80)【LeetCode】1
72 0
|
算法
HOT 100(21~40)【LeetCode】4
HOT 100(21~40)【LeetCode】4
36 0
|
6月前
|
存储 算法
《LeetCode 热题 HOT 100》——寻找两个正序数组的中位数
《LeetCode 热题 HOT 100》——寻找两个正序数组的中位数
|
6月前
|
网络协议
《 LeetCode 热题 HOT 100》——无重复字符的最长子串
《 LeetCode 热题 HOT 100》——无重复字符的最长子串