Day2

41. 缺失的第一个正数

给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

示例 1:

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

示例 2:

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

示例 3:

输入:nums = [7,8,9,11,12]
输出:1

提示:

  • 1 <= nums.length <= 5 * 105
  • -231 <= nums[i] <= 231 - 1

思路:可以采用原地置换方式,目的是把数字本身放到应得的位置,比如数字序列 [4,1,2,-1,9]应该放到[1,2,-1,4,9],

其中如果遇到数字大于0且小于等于数字序列长度才会考虑置换,否则不动,最终遍历得到置换后的序列,遇到的第一个不符合位置的数字位置即为缺失的最小整数,否则如果序列上的数字都在其应有的位置,则放回长度n+1即可

class Solution {
    public int firstMissingPositive(int[] nums) {
        int n = nums.length;
        for (int i = 0; i < n; i++) {
            while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {
                int temp = nums[nums[i] - 1];
                nums[nums[i] - 1] = nums[i];
                nums[i] = temp;
            }
        }
        for (int i = 0; i < n; ++i) {
            if (nums[i] != i + 1) {
                return i + 1;
            }
        }
        return n + 1;
    }
}
  • 时间复杂度:O(N),其中 N是数组的长度。
  • 空间复杂度:O(1)。

32. 最长有效括号

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

示例 1:

输入:s = "(()"
输出:2
解释:最长有效括号子串是 "()"

示例 2:

输入:s = ")()())"
输出:4
解释:最长有效括号子串是 "()()"

示例 3:

输入:s = ""
输出:0

提示:

  • 0 <= s.length <= 3 * 104
  • s[i]'('')'

思路:使用动态规划,我们把dp[i]定义为以s.charAt(i)结尾且包括该结尾字符的最长有效括号的长度;如果s.charAt(i)=='(',显然此时dp[i]==0,否则我们可以根据dp[i-1]计算出 pre=i-1-dp[i-1],如果s.charAt(pre)=='(',证明当前字符可以匹配pre,否则dp[i]=0;此外,如果形如()()这样的形式,我们还要再加上dp[pre-1]的长度。最后取dp最大值即可

class Solution {
    public int longestValidParentheses(String s) {
        int n =s.length();
        if(n<2)return 0;
        int[]dp=new int[n];
        int max=0;
        for(int i=1;i<n;i++){
            if(s.charAt(i)==')'){
                int pre=i-1-dp[i-1];// 保存可能是左括号的位置
                if(pre>=0&&s.charAt(pre)=='('){
                    dp[i]=dp[i-1]+2;
                    if(pre-1>=0){
                        dp[i]+=dp[pre-1];
                    }
                    max=Math.max(max,dp[i]);
                }
            }
        }
        return max;
    }
}

时间复杂度: O(n),其中 n 为字符串的长度。我们只需遍历整个字符串一次,即可将 dp数组求出来。

空间复杂度: O(n)。我们需要一个大小为 n 的 dp 数组。

977. 有序数组的平方

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1:

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

示例 2:

输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums 已按 非递减顺序 排序

思路:使用O(n)的时间复杂度,因为该数组非递减,故在负数区域的平方是递减的,而在正数区域是递增的,可以看做两个有序数组的合并,故同一般的合并有序数组不同,我们在这题可以采用双指针,开辟一个额外数组空间,比较后逆序放入即可

class Solution {
    public int[] sortedSquares(int[] nums) {
         int n=nums.length;
         int[]ans=new int[n];
         //双指针
         for(int i=0,j=n-1,pos=n-1;i<=j;){
             if(nums[i]*nums[i]>nums[j]*nums[j]){
                 ans[pos--]=nums[i]*nums[i];
                 i++;
             }
             else{
                 ans[pos--]=nums[j]*nums[j];
                 j--;
             }
         }
         return ans;
    }
}

时间复杂度:O(n)

空间复杂度:O(n)

最后修改:2024 年 06 月 08 日
如果觉得我的文章对你有用,请随意赞赏