🔥 LeetCode 热题 HOT 100: 31 && 32

70 阅读2分钟

“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”

31. 下一个排列

一、题目描述:

整数数组的一个 排列  就是将其所有成员以序列或线性顺序排列。

例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。

例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。 类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。 而 arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。 给你一个整数数组 nums ,找出 nums 的下一个排列。

必须 原地 修改,只允许使用额外常数空间。

示例 1:

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

 

二、思路分析:

倒序查找相邻的数字中, 右边大于左边的数对 (i,j), 使用 k 记录 i, 从 i 的右边找到最小比nums[k]大的数字, 与 nums[k] 交换, 然后对 k+ 1 到 n - 1 之间的数字进行交换即可

三、AC 代码:

public void nextPermutation(int[] nums) {
    int k = -1;
    int n = nums.length;
    for (int i = n - 1; i > 0; i--) {
        if (nums[i] > nums[i - 1]) {
            k = i - 1;
            break;
        }
    }
    if (k != -1) {
        for (int i = n - 1; i > 0; i--) {
            if (nums[i] > nums[k]) {
                int t = nums[i];
                nums[i] = nums[k];
                nums[k] = t;
                break;
            }
        }
    }

    int l = k + 1;
    int r = n - 1;

    while (l < r) {
        int t = nums[l];
        nums[l] = nums[r];
        nums[r] = t;
        l++;
        r--;
    }
}

32. 最长有效括号

一、题目描述:

给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。

示例 1:

输入:s = "(()"

输出:2

二、思路分析:

  • 动态规划

状态转移: dp[i] 为, 以 i 结尾的字符串中最长有效括号子串的长度

char[i] == '(' 时 dp[i] = 0

char[i] == ')' 时, left = i - 1 - dp[i - 1], 考虑 left 位置的字符, char[left] == '('时

dp[i] = dp[i - 1] + 2 + dp[left - 1]

tip : 注意 Index 的合法性, 不要越界

三、AC 代码:

class Solution {
    public int longestValidParentheses(String s) {

        if (s == null || s.length() == 0) return 0;
        char[] chars = s.toCharArray();
        int[] dp = new int[s.length()];
        int ans = 0;
        for (int i = 0; i < s.length(); i++) {
            char c = chars[i];
            if (c == ')' && i > 0) {
                int l = i - 1 - dp[i - 1];
                if (l >= 0 && chars[l] == '(') {
                    dp[i] = dp[i - 1] + 2;
                    if (l - 1 >= 0) {
                        dp[i] += dp[l - 1];
                    }
                }
            }
            ans = Math.max(ans, dp[i]);
        }
        return ans;
    }
}