LeetCodeHot100 数组 53. 最大子数组和 56. 合并区间 238. 除自身以外数组的乘积 41. 缺失的第一个正数

53. 最大子数组和
https://leetcode.cn/problems/maximum-subarray/description/?envType=study-plan-v2&envId=top-100-liked

public int maxSubArray(int[] nums) {
        int[] dp = new int[nums.length];
        dp[0] = nums[0];
        for (int i = 1; i < nums.length; i++) {
            dp[i] = Math.max(dp[i - 1] + nums[i] , nums[i]);
        }
        int max = dp[0];
        for (int i = 1; i < dp.length; i++) {
            max = dp[i] > max ? dp[i] : max;
        }
        return max;
    }

总结:动态规划,dp数组的含义是当前数字结尾的最大和,每次去比到上一个数的最大和+自己 跟自己谁大,谁大用谁。最后再求最大值。
ps:既然是以当前数字结尾,那就必须带上当前数字。
56. 合并区间
https://leetcode.cn/problems/merge-intervals/description/?envType=study-plan-v2&envId=top-100-liked

public int[][] merge(int[][] intervals) {
        int len = intervals.length;
        // 按照起点排序
        Arrays.sort(intervals,(o1, o2) -> o1[0] - o2[0]);
        // 也可以使用 Stack,因为我们只关心结果集的最后一个区间
        List<int[]> res = new ArrayList<>();
        res.add(intervals[0]);
        for (int i = 1; i < len; i++) {
            int[] curInterval = intervals[i];

            // 每次新遍历到的列表与当前结果集中的最后一个区间的末尾端点进行比较
            int[] peek = res.get(res.size() - 1);

            if (curInterval[0] > peek[1]) {
                res.add(curInterval);
            } else {
                // 注意,这里应该取最大
                peek[1] = Math.max(curInterval[1], peek[1]);
            }
        }
        return res.toArray(new int[res.size()][]);
    }

总结:先排序,让左边界从小到大排序,再循环看每个区间,去看是否需要跟前一个区间合并。
189. 轮转数组
https://leetcode.cn/problems/rotate-array/description/?envType=study-plan-v2&envId=top-100-liked

public void rotate(int[] nums, int k) {
        k %= nums.length;
        reverse(nums, 0, nums.length - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, nums.length - 1);
    }
    public void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start++;
            end--;
        }
    }

总结:首先k对数组长度取余才是真正要动的次数,很关键,之后就是大反转。两次小反转
238. 除自身以外数组的乘积
https://leetcode.cn/problems/product-of-array-except-self/description/?envType=study-plan-v2&envId=top-100-liked

public int[] productExceptSelf(int[] nums) {
        int length = nums.length;
        int[] s1 = new int[length];
        int[] s2 = new int[length];
        int[] res = new int[length];
        s1[0] = nums[0];
        for (int i = 1; i < length; i++) {
            s1[i] = s1[i - 1] * nums[i];
        }
        s2[length - 1] = nums[length - 1];
        for (int i = length -2; i >= 0; i--) {
            s2[i] = s2[i + 1] * nums[i];
        }
        for (int i = 0; i < length; i++) {
            if (i == 0){
                res[i] = s2 [i + 1];
            }else if (i == length - 1){
                res[i] = s1[i - 1];
            }else {
                res[i] = s1[i - 1] * s2[i + 1];
            }
        }
        return res;
    }

总结:S1是前缀积,S2是后缀积,之后在遍历。
41. 缺失的第一个正数
https://leetcode.cn/problems/first-missing-positive/description/?envType=study-plan-v2&envId=top-100-liked

public int firstMissingPositive(int[] nums) {
        int length = nums.length;
        for (int i = 0; i < length; i++) {
            while (nums[i] > 0 && nums[i] <= length && nums[nums[i] - 1] != nums[i]){
                swap(nums,nums[i] - 1,i);
            }
        }
        for (int i = 0; i < length; i++) {
            if (nums[i] != i + 1) {
                return i + 1;
            }
        }
        return length + 1;
    }
    public void swap(int[] nums, int index1, int index2) {
        int temp = nums[index1];
        nums[index1] = nums[index2];
        nums[index2] = temp;
    }

总结:先处理数组,把数组的每个值放到相应位置 ,例如5放到索引为4的位置,再去遍历数组 发现位置不对的数,就返回;

posted @ 2024-03-26 16:09  jeasonGo  阅读(16)  评论(0)    收藏  举报