Leetcode面试经典150题

数组字符串

合并两个有序数组

思路

类似于归并排序,对两个有序数组进行合并即可,但是空间复杂度是O(n+m);

代码

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int[] ans = new int[n + m];
        int i = 0, j = 0;
        int cnt = 0;
        while (i < m && j < n) {
            if (nums1[i] < nums2[j]) {
                ans[cnt++] = nums1[i++];
            } else {
                ans[cnt++] = nums2[j++];
            }
        }
        while(i < m) ans[cnt++] = nums1[i++];
        while(j < n) ans[cnt++] = nums2[j++];
        for (int k = 0; k < cnt; ++k) {
            nums1[k] = ans[k];
        }
    }
}

优化:有一点小优化吧,可以从后往前合并装入nums1的后面,这样不会影响nums1的元素,同样也节省了n+m的空间(本题的数据量小,所以看不出)。

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int i = m - 1;
        int j = n - 1;
        int cnt = n + m - 1;
        while(i >= 0 && j >= 0) {
            if (nums1[i] < nums2[j]) {
                nums1[cnt--] = nums2[j--];
            } else {
                nums1[cnt--] = nums1[i--];
            }
        }
        while(i >= 0) nums1[cnt--] = nums1[i--];
        while(j >= 0) nums1[cnt--] = nums2[j--];
    }
}

双指针

验证回文串

思路

用头指针和尾指针,每次比较的时候必须满足两个指针指向的是数字或字符,其他的符号都跳过。

代码

class Solution {
    public boolean isPalindrome(String s) {
        s = s.toLowerCase();
        int len = s.length();
        int i = 0, j = len - 1;
        char[] ch = s.toCharArray();
        while(i < j) {
            while(i < len && !check(ch[i])) ++i;
            while(j >= 0 && !check(ch[j])) --j;//前面两句是过滤非字符或数字
            if (i > j) {
                break;
            }
            if (ch[i] >= 'a') {
                ch[i] -= 32;
            }
            if (ch[j] >= 'a') {
                ch[j] -= 32;
            }// 如果是字符,则统一转为小写
            if (ch[i] != ch[j]) {
                return false;
            }
            ++i;
            --j;
        }
        return true;
    }
    private boolean check(char ch) {
        if (ch <= 'z' && ch >= 'a') {
            return true;
        }
        if (ch <= 'Z' && ch >= 'z') {
            return true;
        }
        if (ch <= '9' && ch >= '0') {
            return true;
        }
        return false;
    }
}

滑动窗口

长度最小的子数组

思路

由滑动窗口思想:设两个指针,尾指针一直走,当满足某个条件时,头指针也跟着走。
条件:当子数组和大于target时,不断缩小窗口,找到最小的窗口。

代码

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int ans = nums.length;
        int ind = 0;
        int sum = 0;
        for (int i = 0; i < nums.length; ++i) {
            sum += nums[i];
            while (sum >= target) {
                sum -= nums[ind];
                ans = Math.min(ans, i - ind + 1);
                ind++;
            }
        }
        if (ind == 0) { // sum>=target没有执行,不存在子数组
            return 0;
        } 
        return ans;
    }
}

矩阵

有效的数独

思路

创建三个set数组,分别是对存“行”,“列”,“区域”的数字,如果对应的set中有值,那么就不是有效的。否则就添加
这里最主要的是怎样判断是否为同一个区域。
可以先对9x9的表格通过i/3,j/3划分为9个3x3区域然后每个区域的值都是
(0, 0), (0, 1), (0, 2)
(1, 0), (1, 1)…
再通过将二维数组变为一维数组的计算公式i * row + j。就是9个区域。

代码

class Solution {
    public boolean isValidSudoku(char[][] board) {
        Set<Character>[] rows = new HashSet[9];
        Set<Character>[] cols = new HashSet[9];
        Set<Character>[] area = new HashSet[9];
        for (int i = 0; i < 9; ++i) {
            rows[i] = new HashSet<>();
            cols[i] = new HashSet<>();
            area[i] = new HashSet<>();
        }
        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                if (board[i][j] > '9' || board[i][j] < '0') continue;
                if (rows[i].contains(board[i][j])) {
                    return false;
                } else {
                    rows[i].add(board[i][j]);
                }

                if (cols[j].contains(board[i][j])) {
                    return false;
                } else {
                    cols[j].add(board[i][j]);
                }
                int t= i / 3 * 3 + j / 3;
                //System.out.println(i + " " + j + " " + t);
                if (area[t].contains(board[i][j])) {
                    return false;
                } else {
                    area[t].add(board[i][j]);
                }
            }
        }
        return true;
    }
}

哈希表

赎金信

思路

比较r和m的26个字符个数,如果r的某个字符个数大于m的某个字符个数,则r不能由m的字符组成。

代码

class Solution {
    public boolean canConstruct(String r, String m) {
        int[] rCnt = new int[26];
        int[] mCnt = new int[26];
        for (int i = 0; i < r.length(); ++i) {
            rCnt[r.charAt(i) - 'a']++;
        }
        for (int i = 0; i < m.length(); ++i) {
            mCnt[m.charAt(i) - 'a']++;
        }
        for (int i = 0; i < 26; ++i) {
            if (rCnt[i] > mCnt[i]) {
                return false;
            }
        }
        return true;
    }
}

相关推荐

  1. Leetcode面试经典150

    2024-03-15 03:28:01       40 阅读
  2. leecode面试经典150

    2024-03-15 03:28:01       29 阅读
  3. LeetCode 面试经典150 134.加油站

    2024-03-15 03:28:01       37 阅读
  4. leetcode面试经典15010.跳跃游戏 II(C++)

    2024-03-15 03:28:01       41 阅读
  5. 面试经典 150

    2024-03-15 03:28:01       26 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-15 03:28:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-15 03:28:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-15 03:28:01       82 阅读
  4. Python语言-面向对象

    2024-03-15 03:28:01       91 阅读

热门阅读

  1. Winform程序中UI更新延迟

    2024-03-15 03:28:01       37 阅读
  2. 爬虫:爬取新闻内容及图片,存入数据库

    2024-03-15 03:28:01       44 阅读
  3. 怎样把1.ts-10.ts的文件拼接成一个MP4文件

    2024-03-15 03:28:01       47 阅读
  4. C语言统计书本借阅情况

    2024-03-15 03:28:01       38 阅读