刷题笔记(数组)-09

两个数组的交集Ⅱ

题目地址:350. 两个数组的交集 II - 力扣(LeetCode) (leetcode-cn.com)

思路:排序+双指针法

这个方法易懂一点,对我来说是的

  • 首先两个数组排序
  • 定义个返回数组intersection,大小为两个数组中容量较小的那个
  • 定义三个指针,开始循环(判断条件为nums1[index1] <nums2[index2])
  • 当至少有一个指针超出数组范围时,遍历结束
  • 遇到相同元素就添加到返回数组intersection
  • 最后这个方法很巧妙,举个例子,比如intersection数组的大小为3,可是就只有2个交集元素,这是intersection自己的索引就派上用场了,复制数组从(0,index)的范围中,很巧妙的方法
class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        // 新建数组的大小为两个数组中较小的容量
        int[] intersection=new int[Math.min(nums1.length,nums2.length)];
        // 定义指针
        int index1=0;
        int index2 = 0;
        int index=0;
        while (index1< nums1.length&& index2< nums2.length){
            if (nums1[index1] <nums2[index2]){
                index1++;
            }else if (nums1[index1] >nums2[index2]) {
                index2++;
            }else {
                intersection[index]=nums1[index1];
                index1++;
                index2++;
                index++;
            }
        }
        return Arrays.copyOfRange(intersection,0,index);
}
}

复杂度分析

  • 时间复杂度:O(mlogm+nlogn),其中 m 和 n 分别是两个数组的长度。对两个数组进行排序的时间复杂度是 O(mlogm+nlogn),遍历两个数组的时间复杂度是 O(m+n),因此总时间复杂度是 O(mlogm+nlogn)。

  • 空间复杂度:O(min(m,n)),其中 m和n分别是两个数组的长度。为返回值创建一个数组 intersection,其长度为较短的数组的长度,这种实现的空间复杂度为 O(1)。

方法2:哈希表

参考官方题解,才知道Map中有个很巧妙的方法

方法详解:Java HashMap getOrDefault() 方法

思路:

  • 首先判断两个数组中的大小,可以节省空间!
  • 通过map的getOrDefault()方法,这个方法是什么呢?

getOrDefault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值。

语法:hashmap.get(Object key, V defaultValue)

  • 这里的默认值就是0,向map中添加数据,想知道具体添加流程,大家可以自己放进IDEDEBUG,这样更容易理解
  • 首先遍历第一个数组,并在哈希表中记录第一个数组中的每个数字以及对应出现的次数,然后遍历第二个数组,对于第二个数组中的每个数字,如果在哈希表中存在这个数字,则将该数字添加到答案,并减少哈希表中该数字出现的次数。
  • 为了降低空间复杂度,首先遍历较短的数组并在哈希表中记录每个数字以及对应出现的次数,然后遍历较长的数组得到交集
class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
      if(nums1.length> nums2.length){
            return  intersect(nums2, nums1);
        }
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int num : nums1) {
            int count=map.getOrDefault(num, 0)+1;
            map.put(num, count);
        }
        int[] intersection=new int[nums1.length];
        int index = 0;
        for (int num : nums2) {
            int count=map.getOrDefault(num, 0);
            if (count > 0){
                intersection[index++]=num;
                count--;
                map.put(num, count);
            }else {
                map.remove(num);
            }
        }
        System.out.println(Arrays.toString(Arrays.copyOfRange(intersection,0,index)));
        return Arrays.copyOfRange(intersection,0,index);
    }
}

复杂度分析

  • 时间复杂度:O(m+n),其中 m和n分别是两个数组的长度。需要遍历两个数组并对哈希表进行操作,哈希表操作的时间复杂度是 O(1),因此总时间复杂度与两个数组的长度和呈线性关系。

  • 空间复杂度:O(min(m,n)),其 m和n分别是两个数组的长度。对较短的数组进行哈希表的操作,哈希表的大小不会超过较短的数组的长度。为返回值创建一个数组intersection,其长度为较短的数组的长度

买卖股票的最佳时机

思路:

解法1

  • 暴力解法,可以解决,但是在力扣编辑器中会超时,提交不通过,优化下,看解法2
class Solution {
    public int maxProfit(int[] prices) {
        int maxprofit = 0;
        for (int i = 0; i < prices.length - 1; ++i) {
            for (int j = i + 1; j < prices.length; ++j) {
                int profit = prices[j] - prices[i];
                if (profit > maxprofit) {
                    maxprofit = profit;
                }
            }
        }
        return maxprofit;
    }
}

解法2

思路:

  • 最大利润值,想到了利用数学函数max,min

  • 循环遍历,写个测试用例来DEBUG下,看动图!

  • int[] prices={7,1,5,3,6,4};
    
class Solution {
    public int maxProfit(int[] prices) {
       int min = prices[0]; //表示当前股票的最低价格
        int maxProfit= 0; //表示当前股票收益最大值
        for(int i = 1; i <= prices.length - 1; i++){
            min = Math.min(min, prices[i]);
            maxProfit = Math.max(prices[i] - min, maxProfit);
        }
        return maxProfit;
    }
}

大家可以自己DEBUG这样印象更深!

代码均由力扣编译器,提交通过,描述编写不当地方还请大家评论区指出💪!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值