刷题笔记(数组)-09
Posted 康小庄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了刷题笔记(数组)-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中添加数据,想知道具体添加流程,大家可以自己放进
IDE
中DEBUG
,这样更容易理解- 首先遍历第一个数组,并在哈希表中记录第一个数组中的每个数字以及对应出现的次数,然后遍历第二个数组,对于第二个数组中的每个数字,如果在哈希表中存在这个数字,则将该数字添加到答案,并减少哈希表中该数字出现的次数。
- 为了降低空间复杂度,首先遍历较短的数组并在哈希表中记录每个数字以及对应出现的次数,然后遍历较长的数组得到交集
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
这样印象更深!
代码均由力扣编译器,提交通过,描述编写不当地方还请大家评论区指出💪!
以上是关于刷题笔记(数组)-09的主要内容,如果未能解决你的问题,请参考以下文章