0
点赞
收藏
分享

微信扫一扫

LeeCode刷题(二)

后来的六六 2022-03-10 阅读 74

LeeCode题库Solution53、121、217、242、349

Solution53最大子数组和

思路:res作为历史最佳解,sum作为当前最佳解,每一次遍历nums数组时,都去动态更新res和sum。 动态更新的逻辑为: 如果sum为正数,在有res记录历史最佳值的条件下,可以有恃无恐地继续累加,创造新高;如果sum为负数,不管下一次遍历值是多少累加后都不会大于它,见风使舵果断取下一个遍历值为当前最佳解。 每一轮遍历结束后,如果当前最佳解优于历史最佳解,就会升任历史最佳解。       动!!态!!规!!划!!

//如果sum为正数,那么继续向后累加并记录下sum的最大值,继续向后累加的原因是sum有变大的可能。
//如果sum为负数,那么sum+nums[i]必然小于nums[i],所以sum = nums[i].
    public int maxSubArray(int[] nums) {
        int res = nums[0];
        int sum = 0;
        for (int num : nums) {
            if (sum > 0)
                sum += num;
            else
                sum = num;
            res = Math.max(res, sum);
        }
        return res;
    }

Solution121买卖股票的最大收益

 动态规划 前i天的最大收益 = max{前i-1天的最大收益,第i天的价格-前i-1天中的最小价格}

//低价买高价卖
//记录【今天之前买入的最小值】
//计算【今天之前最小值买入,今天卖出的获利】,也即【今天卖出的最大获利】
//比较【每天的最大获利】,取最大值即可
public class S121买卖股票 {
    public int maxProfit(int[] prices) {
        if(prices.length <= 1)
            return 0;
        int min = prices[0], max = 0;
        for(int i = 1; i < prices.length; i++) {
            max = Math.max(max, prices[i] - min);
            min = Math.min(min, prices[i]);
        }
        return max;
    }
}

Solution217存在重复元素

方法一 数组排序

排序在对数字从小到大排序之后,数组的重复元素一定出现在相邻位置中。因此,我们可以扫描已排序的数组,每次判断相邻的两个元素是否相等,如果相等则说明存在重复的元素。

    public boolean containsDuplicate(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length;
        for (int i = 0; i < n - 1; i++) {
            if (nums[i] == nums[i + 1]) {
                return true;
            }
        }
        return false;
    }

方法二 HashSet

时间空间复杂度都是O(n).

//HashSet  利用哈希表不会存储两个相同元素的特性
    public boolean containsDuplicate01(int[] nums) {
        HashSet<Integer> hashSet = new HashSet<>();
        for (int num : nums) {
            if (hashSet.add(num) == false) {
                return true;
            }
        }
        return false;
    }

Solution242有效字母异位词

import java.util.Arrays;

//给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
public class S242有效的符号 {
    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }
        char[] sChars = s.toCharArray();
        char[] tChars = t.toCharArray();
        Arrays.sort(sChars);
        Arrays.sort(tChars);
        return Arrays.equals(sChars, tChars);
    }
}

Solution349两数组交集

总结   先排序,然后是用双指针先遍历两容器,重复则插入到新容器

时间复杂度:O(m \log m+n \log n)O(mlogm+nlogn)

细节:对两个数组进行排序,然后使用两个指针遍历两个数组。可以预见的是加入答案的数组的元素一定是递增的,为了保证加入元素的唯一性,我们需要额外记录变量 \textit{pre}pre 表示上一次加入答案数组的元素。

初始时,两个指针分别指向两个数组的头部。每次比较两个指针指向的两个数组中的数字,如果两个数字不相等,则将指向较小数字的指针右移一位,如果两个数字相等,且该数字不等于 \textit{pre}pre ,将该数字添加到答案并更新 \textit{pre}pre 变量,同时将两个指针都右移一位。当至少有一个指针超出数组范围时,遍历结束。

public int[] intersection(int[] nums1, int[] nums2) {
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int length1 = nums1.length, length2 = nums2.length;
        int[] intersection = new int[length1 + length2];
        int index = 0, index1 = 0, index2 = 0;
        while (index1 < length1 && index2 < length2) {
            int num1 = nums1[index1], num2 = nums2[index2];
            if (num1 == num2) {
                // 保证加入元素的唯一性
                if (index == 0 || num1 != intersection[index - 1]) {
                    intersection[index++] = num1;
                }
                index1++;
                index2++;
            } else if (num1 < num2) {
                index1++;
            } else {
                index2++;
            }
        }
        return Arrays.copyOfRange(intersection, 0, index);
    }
举报

相关推荐

0 条评论