hot100打卡——day14

20. 有效的括号

https://leetcode.cn/problems/valid-parentheses/description/?envType=problem-list-v2&envId=2cktkvj

java 复制代码
class Solution {
    public boolean isValid(String s) {
        Deque<Character> deque = new LinkedList<>();
        char[] arr = s.toCharArray();
        int n = arr.length;
        if (n % 2 != 0) return false;
        for (char c : arr) {
            if (c == '(' || c == '{' || c == '[') {
                deque.push(c);
            } else {
                if (deque.isEmpty()) return false;
                else {
                    Character ch = deque.pop();
                    if (!isValid(ch, c)) return false;
                }
            }
        }
        return deque.isEmpty();
    }

    static boolean isValid(char c1, char c2) {
        if (c1 == '(' && c2 == ')') return true;
        if (c1 == '{' && c2 == '}') return true;
        if (c1 == '[' && c2 == ']') return true;
        return false;
    }

}

用一个栈就行

19. 删除链表的倒数第 N 个结点

https://leetcode.cn/problems/remove-nth-node-from-end-of-list/description/?envType=problem-list-v2&envId=2cktkvj

java 复制代码
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {        
        ListNode cur = head;
        // 计算一下总长度
        int cnt = 0;
        while (cur != null) {
            cnt ++;
            cur = cur.next;
        }
        
        // 找要删除的位置
        int t = cnt - n + 1;
        // 要删除的是头节点
        if (t == 1) return head.next;
        cur = head;
        for (int i = 1; i < t - 1; i++) {
            cur = cur.next;
        }
        // 现在cur指向的是 t - 1 的位置
        cur.next = cur.next.next;
        return head;
    }
}

解题思路:先看一下总共有几个节点,然后推算出要删除的节点是下标,然后先找到要删除的节点的前一个节点,做一下cur.next = cur.next.next;就行

17. 电话号码的字母组合

https://leetcode.cn/problems/letter-combinations-of-a-phone-number/description/?envType=problem-list-v2&envId=2cktkvj

java 复制代码
class Solution {
    static String[] map = new String[] {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    static List<String> res;
    public List<String> letterCombinations(String digits) {
        res = new ArrayList<>();
        if (digits.isEmpty()) return res;
        dfs(digits.toCharArray(), 0, new StringBuilder());
        return res;
    }

    static void dfs(char[] arr, int idx, StringBuilder sb) {
        if (idx == arr.length) {
            res.add(sb.toString());
            return;
        }
        int n = arr[idx] - '0';
        String str = map[n];
        int len = str.length();
        for (int i = 0; i < len; i++) {
            sb.append(str.charAt(i));
            dfs(arr, idx + 1, sb);
            sb.deleteCharAt(sb.length() - 1);
        }
    }
}

解题思路:回溯法,用idx标识当前是在解决digits中第几个字符的枚举情况

15. 三数之和

https://leetcode.cn/problems/3sum/description/?envType=problem-list-v2&envId=2cktkvj

java 复制代码
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        int n = nums.length;
        Arrays.sort(nums);
        for (int i = 0; i < n - 2; i++) {
            // 去重
            if (i > 0 && nums[i] == nums[i-1]) continue;

            int l = i + 1;
            int r = n - 1;
            while(l < r) {
                int sum = nums[i] + nums[l] + nums[r];
                if (sum == 0) {
                    res.add(Arrays.asList(nums[i], nums[l], nums[r]));
                    // 去重
                    while (l < r && nums[l] == nums[l + 1]) l ++;
                    while (l < r && nums[r] == nums[r - 1]) r --;
                    l ++; r --;
                }
                else if (sum > 0) r --;
                else l ++;
            }
        }
        return res;
    }
}

解题思路:相当于三个指针,第一个指针就是从头到尾扫一遍,另外两个指针分别在 i+1 和 n-1 的位置开始

11. 盛最多水的容器

https://leetcode.cn/problems/container-with-most-water/description/?envType=problem-list-v2&envId=2cktkvj

java 复制代码
class Solution {
    public int maxArea(int[] height) {
        int n = height.length;
        int l = 0;
        int r = n - 1;
        int ans = 0;
        while (l < r) {
            int h = Math.min(height[l], height[r]);
            ans = Math.max(ans, h * (r - l));
            
            // 去掉一些无效选项
            while(l < r && height[l] <= h) l ++;
            while(l < r && height[r] <= h) r --;
        }
        return ans;
    }
}

解题思路:这道题其实就是典型的双指针,我们只需要定义两个指针分别枚举容器的左右木板就行

每次取小的那个作为高度,就能计算出来了

然后进行指针移动的时候是不是可以手动的去掉一些无效的选项,比如指针下一步指向的高度还没当前的高度高,又因为指针在往中间移动,宽度肯定变小,那么这个选项是不是可以直接跳过

10. 正则表达式匹配

https://leetcode.cn/problems/regular-expression-matching/description/?envType=problem-list-v2&envId=2cktkvj

java 复制代码
class Solution {
    public boolean isMatch(String s, String p) {
        int n = s.length();
        int m = p.length();

        s = " " + s;
        p = " " + p;

        boolean[][] dp = new boolean[n + 1][m + 1];
        dp[0][0] = true;
        for (int i = 0; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (j + 1 <= m && p.charAt(j + 1) == '*') continue;
                if (p.charAt(j) == '*') {
                    dp[i][j] = (j >= 2 && dp[i][j-2]) || (i >= 1 && dp[i-1][j]) && (s.charAt(i) == p.charAt(j-1) || p.charAt(j-1) == '.');
                } else {
                    dp[i][j] = (i >= 1 && j >= 1 && dp[i-1][j-1]) && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.');
                }
            }
        }
        
        return dp[n][m];
    }
}

当 p[j] 不是 '*' 的时候就是直接看 dp[i-1][j-1] 是否为true且 s[i] 是否等于 p[j] 或是 p[j] 等于 '.'

当 p[j] 是 '*' 的时候,就需要推到一下地推公式

考虑一下 p 中的 这个 * 匹配 s 中 的字符个数,需要从匹配0次,匹配1次,匹配2次,......

那么就可以退出如下式子(然后之所以是取 j - 2 的原因是因为,*是和它前一个字符搭配的,不是单独去匹配):

式子1:f(i, j) = f(i, j - 2) || (f(i-1, j - 2) && (s[i] == p[j-1])) || (f(i-2, j-2) && (s[i-1] ==p[j-1]) && s[i] ==p[j-1])......

式子2:f(i-1, j) = f(i-1, j - 2) || (f(i-2, j - 2) && (s[i-1] == p[j-1])) || (f(i-3, j-2) && (s[i-2] ==p[j-1]) && s[i-1] ==p[j-1])......

可以发现 高亮部分是能对应上的,那么是不是可以退出 式子1后面部分可以替换成 f(i-1, j) && (s[i] ==p[j-1])

整合一下结论:f(i, j) = f(i, j - 2) || f(i-1, j) && (s[i] ==p[j-1])

最后要注意的就是出现下标的时候需要考虑越界的情况,代码里面也有具体的实现,可以直接看代码理解

相关推荐
DLGXY2 小时前
数据结构——双向循环链表的建立、添加、遍历(十三)
数据结构·链表
liliangcsdn2 小时前
RL中GAE的计算过程详解
大数据·人工智能·算法
Hgfdsaqwr2 小时前
内存泄漏检测与防范
开发语言·c++·算法
C雨后彩虹2 小时前
优雅子数组
java·数据结构·算法·华为·面试
一嘴一个橘子2 小时前
springmvc 全局异常处理 and 拦截器
java
wangmengxxw2 小时前
SpringAI-mysql
java·数据库·人工智能·mysql·springai
漫随流水2 小时前
leetcode回溯算法(46.全排列)
数据结构·算法·leetcode·回溯算法
Coder_Boy_2 小时前
基于SpringAI的在线考试系统-数据库设计核心业务方案
java·数据库·spring boot·ddd·tdd
一嘴一个橘子2 小时前
springmvc 参数校验
java