力扣面试经典150题(五)

76

76. 最小覆盖子串

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

注意:

  • 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
  • 如果 s 中存在这样的子串,我们保证它是唯一的答案。
class Solution {
    public String minWindow(String s, String t) {
        if (s.length() < t.length()) {
            return "";
        }
        HashMap<Character, Integer> hash1 = new HashMap<>();
        HashMap<Character, Integer> hash2 = new HashMap<>();
        for (int i = 0; i < t.length(); i++) {
            char c1 = t.charAt(i);
            hash1.put(c1, hash1.getOrDefault(c1, 0) + 1);
        }
        int left = 0;
        int right = 0;
        int vaild = 0;
        int window = Integer.MAX_VALUE;
        int start = 0;
        while (right < s.length()) {
            char c2 = s.charAt(right);
            right++;
            hash2.put(c2, hash2.getOrDefault(c2, 0) + 1);
            if (hash1.containsKey(c2) && hash1.get(c2).equals(hash2.get(c2))) {
                vaild++;
            }
            while (vaild == hash1.size()) {
                if(window!=Math.min(window,right-left)){
                    window=Math.min(window,right-left);
                    start = left;
                }
                char c3 = s.charAt(left);
                if (hash1.containsKey(c3) && hash1.get(c3).equals(hash2.get(c3))) {
                    vaild--;
                }
                hash2.put(c3,hash2.get(c3)-1);//更新值
                left++;
            }
        }
        if (window == Integer.MAX_VALUE) {
            return "";
        } else {
            return s.substring(start,start+window);
        }
    }
}

36

36. 有效的数独

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
class Solution {
    public boolean isValidSudoku(char[][] board) {
        HashSet<String> count = new HashSet<>();
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                char c = board[i][j];
                if (c != '.') {
                    if (!count.add(c + "row" + i) || !count.add(c + "column" + j)
                            || !count.add(c + "block" + i / 3 + "-" + j/3)) {// 通过字符对比判断是否重合
                        return false;
                    }
                }
            }
        }
        return true;
    }
}

class Solution {
    public boolean isValidSudoku(char[][] board) {
        int[] nums = new int[10];
        //查行
//将数组初始化为全0,按行遍历,将board里的值当做数组下标
//若之前已经存在,则在数组中这个位置为1,否则为0
        for(int x = 0 ;x < 9 ; x++){
            setZero(nums);
            for(int y = 0 ; y < 9 ; y++){
                if(board[x][y] != '.'){
                    if(nums[board[x][y]-'0'] == 1){
                        return false;
                    }else{
                        nums[board[x][y]-'0'] = 1;
                    }
                }
            }
        }
        //test each column
        for(int x = 0 ;x < 9 ; x++){
            setZero(nums);
            for(int y = 0 ; y < 9 ; y++){
                if(board[y][x] != '.'){
                    if(nums[board[y][x]-'0'] == 1){
                        return false;
                    }else{
                        nums[board[y][x]-'0'] = 1;
                    }
                }
            }
        }

        //test each cube
        for(int x = 0 ;x < 3 ; x++){
            for(int y = 0 ; y < 3 ; y++){
                setZero(nums);
                for(int i = 0; i < 3 ; i++){
                    for(int j=0; j < 3; j++){
                        if(board[y*3+i][x*3+j] != '.'){
                            if(nums[board[y*3+i][x*3+j]-'0'] == 1){
                                return false;
                            }else{
                                nums[board[y*3+i][x*3+j]-'0'] = 1;
                            }
                        }
                    }
                }
            }
        }
        return true;
    }

    public void setZero(int[] nums){
        for(int x = 0; x < nums.length ;x ++){
            nums[x] = 0;
        }
    }
}

54

54. 螺旋矩阵

提示

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        int r=matrix.length;
        int l=matrix[0].length;
        int i=0,j=0;
        boolean[][] visitd=new boolean[r][l];
        ArrayList<Integer> list = new ArrayList<>();
        while(list.size()<r*l){
            //往右
            while(i>=0&&j>=0&&i<r&&j<l&&!visitd[i][j]){
                list.add(matrix[i][j]);
                visitd[i][j]=true;
                    j++;
            }
            j--;
            i++;
            //往下
            while(i>=0&&j>=0&&i<r&&j<l&&!visitd[i][j]){
                list.add(matrix[i][j]);
                visitd[i][j]=true;
                i++;
            }
            i--;
            j--;
            //往左
            while(i>=0&&j>=0&&i<r&&j<l&&!visitd[i][j]){
                list.add(matrix[i][j]);
                visitd[i][j]=true;
                j--;
            }
            j++;
            i--;
            //往上
            while(i>=0&&j>=0&&i<r&&j<l&&!visitd[i][j]){
                list.add(matrix[i][j]);
                visitd[i][j]=true;
                i--;
            }
            i++;
            j++;
        }
        return list;
    }
}

48

48. 旋转图像

给定一个 × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

class Solution {
    public void rotate(int[][] matrix) {
        int temp = 0;
        for(int i=0;i<matrix.length;i++){
            for(int j=0;j<i;j++){
                temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }
     //再镜像对称
     for(int j =0;j<matrix.length/2;j++){
         for(int i=0;i<matrix[0].length;i++){
             temp = matrix[i][j];
             matrix[i][j] = matrix[i][matrix.length-j-1];
             matrix[i][matrix.length-j-1] = temp;
         }
     }

    }
}

73

73. 矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法

class Solution {
    public void setZeroes(int[][] matrix) {
        HashSet<Integer> rows = new HashSet<>();
        HashSet<Integer> cols = new HashSet<>();
        
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                if (matrix[i][j] == 0) {
                    rows.add(i);
                    cols.add(j);
                }
            }
        }
        
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                if (rows.contains(i) || cols.contains(j)) {
                    matrix[i][j] = 0;
                }
            }
        }
    }
}

289

289. 生命游戏

根据 百度百科 , 生命游戏 ,简称为 生命 ,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。

给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态: 1 即为 活细胞 (live),或 0 即为 死细胞 (dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:

  1. 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
  2. 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
  3. 如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
  4. 如果死细胞周围正好有三个活细胞,则该位置死细胞复活;

下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。给你 m x n 网格面板 board 的当前状态,返回下一个状态。

class Solution {
    public void gameOfLife(int[][] board) {
        int m = board.length;
        int n = board[0].length;
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                int count = 0;
                if(i - 1 >= 0 && (board[i - 1][j] == 1 || board[i - 1][j] == -1)) count++;
                if(i - 1 >= 0 && j - 1 >= 0 && (board[i - 1][j - 1] == 1 || board[i - 1][j - 1] == -1)) count++;
                if(i - 1 >= 0 && j + 1 < n && (board[i - 1][j + 1] == 1 || board[i - 1][j + 1] == -1)) count++;
                if(j - 1 >= 0 && (board[i][j - 1] == 1 || board[i][j - 1] == -1)) count++;
                if(j - 1 >= 0 && i + 1 < m && (board[i + 1][j - 1] == 1 || board[i + 1][j - 1] == -1)) count++;
                if(j + 1 < n && (board[i][j + 1] == 1 || board[i][j + 1] == -1)) count++;
                if(j + 1 < n && i + 1 < m && (board[i + 1][j + 1] == 1 || board[i + 1][j + 1] == -1)) count++;
                if(i + 1 < m && (board[i + 1][j] == 1 || board[i + 1][j] == -1)) count++;
                if((board[i][j] == 1 || board[i][j] == -1) && (count < 2 || count > 3)){
                    board[i][j] = -1;
                } else if((board[i][j] == 0 || board[i][j] == -2) && count == 3){
                    board[i][j] = -2;
                }
            }
        }

        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(board[i][j] == -1) board[i][j] = 0;
                if(board[i][j] == -2) board[i][j] = 1;
            }
        }
    }
}

383

383. 赎金信

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false 。

magazine 中的每个字符只能在 ransomNote 中使用一次。

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        HashMap<Character, Integer> hash1 = new HashMap<>();
        HashMap<Character, Integer> hash2 = new HashMap<>();
        char[] c1 = ransomNote.toCharArray();
        char[] c2 = magazine.toCharArray();
        for (char s1 : c1) {
            hash1.put(s1, hash1.getOrDefault(s1, 0) + 1);
        }
        for (char s2 : c2) {
            hash2.put(s2, hash2.getOrDefault(s2, 0) + 1);
        }
        for(char s3 :hash1.keySet()){
            int p1 = hash1.get(s3);
            int p2 = hash2.getOrDefault(s3,0);
            if(p1>p2){
                return false;
            }
        }
        return true;
    }
}

205

205. 同构字符串

给定两个字符串 s 和 t ,判断它们是否是同构的。

如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。

每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。

class Solution {
    public boolean isIsomorphic(String s, String t) {
         HashMap<Character, Character> hash = new HashMap<>();
        char[] c1 = s.toCharArray();
        char[] c2 = t.toCharArray();
        for(int i=0;i<c1.length;i++){
            if(hash.containsKey(c1[i])){
                if(hash.get(c1[i])!=c2[i]){
                    return false;
                }
            }else{
               if(hash.containsValue(c2[i])){
                return false;
            }
            hash.put(c1[i],c2[i]); 
            }
        }
        return true;
    }
}

相关推荐

  1. 经典150:多数元素

    2024-01-19 10:52:02       15 阅读
  2. 经典150:逆波兰表达式求值

    2024-01-19 10:52:02       16 阅读
  3. 经典150第四十:存在重复元素 II

    2024-01-19 10:52:02       15 阅读
  4. 经典150十二:简化路径

    2024-01-19 10:52:02       11 阅读
  5. 经典150十三:基本计算器

    2024-01-19 10:52:02       14 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-19 10:52:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-19 10:52:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-19 10:52:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-19 10:52:02       20 阅读

热门阅读

  1. Git从一个仓库合并另一个仓库的某一次提交

    2024-01-19 10:52:02       28 阅读
  2. [go] 命令模式

    2024-01-19 10:52:02       30 阅读
  3. Kotlin——面向对象编程

    2024-01-19 10:52:02       44 阅读
  4. 解释 Git 的基本概念和使用方式

    2024-01-19 10:52:02       28 阅读
  5. SQLite 3.45.0 发布!

    2024-01-19 10:52:02       38 阅读
  6. dayjs的使用

    2024-01-19 10:52:02       35 阅读
  7. C++程序设计(第3版)谭浩强 第8章 习题

    2024-01-19 10:52:02       33 阅读
  8. opencv的SIFT样例(CPP/python)

    2024-01-19 10:52:02       35 阅读
  9. NVIDIA jetson编译opencv 源码 python版本

    2024-01-19 10:52:02       28 阅读