HOT100--Day23--153. 寻找旋转排序数组中的最小值,4. 寻找两个正序数组的中位数,20. 有效的括号

HOT100--Day23--153. 寻找旋转排序数组中的最小值,4. 寻找两个正序数组的中位数,20. 有效的括号

每日刷题系列。今天的题目是《力扣HOT100》题单。

题目类型:二分查找,栈。

关键:

今天的题目都是"多次二分"

153题,掌握"旋转排序数组"的特性和操作。

20题,可以用stack,可以用字符数组原地模拟栈,可以用switch case

153. 寻找旋转排序数组中的最小值

思路:

和最后一个元素比较。

二分查找[0,n-2]的内容,n-1不用管,是比较的对象。

如果x比最后一个数小,要么是最小值,要么x在最小值右侧。right = mid - 1;

如果x大于等于最后一个数。一定有两段,且目前x在第一段。left = mid + 1;

java 复制代码
class Solution {
    public int findMin(int[] nums) {
        int n = nums.length;
        int left = 0;
        int right = n - 2;

        // 二分查找[0,n-2]的内容,n-1不用管,是比较的对象
        while (left <= right) {
            int mid = left + ((right - left) >> 1);
            int x = nums[mid];

            // 如果x比最后一个数小,要么是最小值,要么x在最小值右侧
            if (x < nums[n - 1]) {
                right = mid - 1;
            } else {

                // 如果x大于等于最后一个数。一定有两段,且目前x在第一段。
                left = mid + 1;
            }
        }
        return nums[right + 1];
    }
}
  • 情况一:最小值在最左边,整个数组递增。会一直执行right = mid -1;left一直等于0。最后在right = -1的时候退出循环,这时候返回nums[right+1],就是nums[0],正确。
  • 情况二:最小值在最右边,其实也是分成了两端了。会一直执行left = mid +1;right一直等于n-2直到退出循环。这时候返回nums[right+1],就是nums[n-1],正确。
  • 其他情况:分成两段,全局最小值,在右段的第一个。最终会因为left>right退出循环,而退出循环时,right会在第一段的最后一个元素,也就是全局最大值的地方,返回nums[right+1],就是第二段的第一个元素,全局最小值。(这里也是退出循环时,left的位置)

4. 寻找两个正序数组的中位数

思路:

先不做,跳过,二刷再做。

java 复制代码
class Solution {
    public double findMedianSortedArrays(int[] a, int[] b) {
        if (a.length > b.length) {
            // 交换 a 和 b
            int[] tmp = a;
            a = b;
            b = tmp;
        }

        int m = a.length;
        int n = b.length;
        // 循环不变量:a[left] <= b[j+1]
        // 循环不变量:a[right] > b[j+1]
        int left = -1;
        int right = m;
        while (left + 1 < right) { // 开区间 (left, right) 不为空
            int i = (left + right) / 2;
            int j = (m + n + 1) / 2 - i - 2;
            if (a[i] <= b[j + 1]) {
                left = i; // 缩小二分区间为 (i, right)
            } else {
                right = i; // 缩小二分区间为 (left, i)
            }
        }

        // 此时 left 等于 right-1
        // a[left] <= b[j+1] 且 a[right] > b[j'+1] = b[j],所以答案是 i=left
        int i = left;
        int j = (m + n + 1) / 2 - i - 2;
        int ai = i >= 0 ? a[i] : Integer.MIN_VALUE;
        int bj = j >= 0 ? b[j] : Integer.MIN_VALUE;
        int ai1 = i + 1 < m ? a[i + 1] : Integer.MAX_VALUE;
        int bj1 = j + 1 < n ? b[j + 1] : Integer.MAX_VALUE;
        int max1 = Math.max(ai, bj);
        int min2 = Math.min(ai1, bj1);
        return (m + n) % 2 > 0 ? max1 : (max1 + min2) / 2.0;
    }
}

20. 有效的括号

思路:

把字符数组模拟成栈,空间复杂度O(1)。

注意,Java字符串转成字符数组时,会复制,所以空间复杂度是O(n)。可以用指针的语言的空间复杂度是O(1)

  1. 如果是左括号?进栈
  2. 如果是右括号?
    1. 首先栈内要有元素,检查跟栈顶元素是否匹配
      1. 匹配,出栈
      2. 不匹配,返回false
  3. 最后需要是空栈
java 复制代码
class Solution {
    // 思路:利用字符数组作栈
    public boolean isValid(String s) {
        char[] ch = s.toCharArray();
        int top = 0;
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            // 如果是左括号?进栈
            if (isLeft(c)) {
                ch[top++] = c;
            } else {
                // 如果是右括号?
                // 首先栈内要有元素,检查跟栈顶元素是否匹配
                if (top > 0 && isMatched(ch[top - 1], c)) {
                    // 匹配,出栈
                    top--;
                } else {
                    // 不匹配,返回false
                    return false;
                }
            }
        }
        // 最后需要是空栈
        return top == 0;
    }

    private boolean isLeft(char c) {
        if (c == '(' || c == '{' || c == '[') {
            return true;
        } else {
            return false;
        }
    }

    private boolean isMatched(char a, char b) {
        if (a == '(' && b == ')' || a == '[' && b == ']' || a == '{' && b == '}') {
            return true;
        } else {
            return false;
        }
    }
}

思路:

使用stack库函数。其实大同小异。

java 复制代码
class Solution {
    // 思路:利用字符数组作栈
    public boolean isValid(String s) {
        char[] ch = s.toCharArray();
        Deque<Character> stack = new ArrayDeque<>();
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            // 如果是左括号?进栈
            if (isLeft(c)) {
                stack.push(c);
            } else {
                // 如果是右括号?
                // 首先栈内要有元素,检查跟栈顶元素是否匹配
                if (!stack.isEmpty() && isMatched(stack.peek(), c)) {
                    // 匹配,出栈
                    stack.pop();
                } else {
                    // 不匹配,返回false
                    return false;
                }
            }
        }
        // 最后需要是空栈
        return stack.isEmpty();
    }

    private boolean isLeft(char c) {
        if (c == '(' || c == '{' || c == '[') {
            return true;
        } else {
            return false;
        }
    }

    private boolean isMatched(char a, char b) {
        if (a == '(' && b == ')' || a == '[' && b == ']' || a == '{' && b == '}') {
            return true;
        } else {
            return false;
        }
    }
}

思路:

使用switch case

java 复制代码
class Solution {
    public boolean isValid(String s) {
        char[] ss = s.toCharArray();
        Deque<Character> stack = new ArrayDeque<>();
        for (char c : ss) {
            switch(c){
                case '(':
                case '[':
                case '{': stack.push(c);break;
                case ')': if(stack.isEmpty()||stack.pop()!='(') return false;break;
                case ']': if(stack.isEmpty()||stack.pop()!='[') return false;break;
                case '}': if(stack.isEmpty()||stack.pop()!='{') return false;break;
            }
        }
        return stack.isEmpty();
    }
}
相关推荐
w_w方圆2 天前
1.序列式容器-vector&list
链表·stl·vector·数组·标准模板库
玩镜的码农小师兄5 天前
[从零开始面试算法] (04/100) LeetCode 136. 只出现一次的数字:哈希表与位运算的巅峰对决
c++·算法·leetcode·面试·位运算·hot100
Dream it possible!7 天前
LeetCode 面试经典 150_栈_简化路径(53_71_C++_中等)(栈+stringstream)
c++·leetcode·面试·
Dream it possible!7 天前
LeetCode 面试经典 150_栈_有效的括号(52_20_C++_简单)(栈+哈希表)
c++·leetcode·面试··哈希表
Chloeis Syntax8 天前
栈和队列笔记2025-10-12
java·数据结构·笔记·
代码充电宝9 天前
LeetCode 算法题【中等】189. 轮转数组
java·算法·leetcode·职场和发展·数组
Syntech_Wuz10 天前
从 C 到 C++:容器适配器 std::stack 与 std::queue 详解
数据结构·c++·容器··队列
Espresso Macchiato11 天前
Leetcode 3710. Maximum Partition Factor
leetcode·职场和发展·广度优先遍历·二分法·leetcode hard·leetcode 3710·leetcode双周赛167
nju_spy13 天前
力扣每日一题(二)任务安排问题 + 区间变换问题 + 排列组合数学推式子
算法·leetcode·二分查找·贪心·排列组合·容斥原理·最大堆
要一起看日出14 天前
数据结构-----栈&队列
java·数据结构··队列