学习目标:
本次学习目标为 力扣初级算法-数组,其中主要的LC如下:
- 两个数组的交集 II
- 加一
学习内容:
- 两个数组的交集 II (链接)
给定两个数组,编写一个函数来计算它们的交集。示例1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]示例2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]说明:
输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。
我们可以不考虑输出结果的顺序。进阶:
如果给定的数组已经排好序呢?你将如何优化你的算法?
如果 nums1 的大小比 nums2 小很多,哪种方法更优?
如果 nums2 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
解题思路:
- 解法一: 排序后类二分查找
- 边界问题:可先判断数组长度,取数组小者作为循环项
- 代码逻辑过程:
- 先对两个数组进行排序;
- 比较数组1与数组2的最小长度,最小长度声明为 whileSize,作为 while 循环的大小 ,同时声明 i 、j 作为数组1 和数组2 当前循环的坐标;
- while 循环数组,while 循环条件为 i < num1.size && j < num2.size && i < whileSize && j < whileSize
- 当 num1[i] 小于 num2[j] 时,i++ ,往右继续查找相同项
- 当 num1[i] 大于 num2[j] 时,j++ 往右继续查找相同项
- 当 num1[i] 等于 num2[j] 时,则当前元素为 num1 与 num2 相同的元素
- 代码实现:
public static int[] intersect01(int[] nums1, int[] nums2) {
Arrays.sort(nums1);
Arrays.sort(nums2);
int i = 0;
int j = 0;
List<Integer> list = new ArrayList<>();
int whileSize = Math.max(nums1.length, nums2.length);
while (i < nums1.length && j < nums2.length && i<= whileSize && j<= whileSize){
if (nums1[i] < nums2[j]){
i++;
}else if (nums1[i] > nums2[j]){
j++;
}else {
list.add(nums1[i]);
}
}
int index = 0;
int[] result = new int[list.size()];
for (Integer listIndex : list) {
result[listIndex] = list.get(listIndex);
}
return result;
}
-
解法二:使用Map
-
边界问题:可先判断数组长度,取数组小者作为循环项
-
解题思路:
-
循环遍历入参数组,将数组的元素作为 Map 的 Key ,出现的次数作为 Map 的 value,然后判断两入参数组对应 Map 的 key size,取key.size 较小的map 做循环,循环过程中,当两入参的 Map 中都存在相同的元素时,拿到对应的 Value,此时再根据 Value 的大小作为 循环插入返回数组中。
-
代码逻辑过程:
-
待补充
-
代码实现:
public static int[] intersect03(int[] nums1, int[] nums2) {
List<Integer> resultList = new ArrayList<>();
Map<Integer, Integer> firstMap = new HashMap<>();
for (int i : nums1) {
firstMap.merge(i, 1, Integer::sum);
}
Map<Integer, Integer> secondMap = new HashMap<>();
for (int i : nums2) {
secondMap.merge(i, 1, Integer::sum);
}
Map<Integer, Integer> map = firstMap.size() > secondMap.size() ? secondMap : firstMap;
for (Integer integer : map.keySet()) {
if (firstMap.containsKey(integer) && secondMap.containsKey(integer)) {
Integer integer1 = firstMap.get(integer);
Integer integer2 = secondMap.get(integer);
int finalInt = integer1 >= integer2 ? integer2 : integer1;
for (int i = 1; i <= finalInt; i++) {
resultList.add(integer);
}
}
}
int index = 0;
int[] res = new int[resultList.size()];
for (int k = 0; k < resultList.size(); k++) {
res[index++] = resultList.get(k);
}
return res;
}
- 只出现一次的数字 (链接)
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?示例1:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。示例2:
输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。示例3:
输入:digits = [0]
输出:[1]
-
解法一:
-
边界问题:
- 考虑元素为9,但元素9 + 1 之后,需要向前进位;
- 考虑数组的第一个元素为 9 的情况,此时数组的元素个数需要加多一位 为1 的元素;
-
解题思路:
- 主要的难点是边界问题,当数组的元素为9时,需要将元素置为0,同时对应的下一位需要加上一。
-
代码逻辑过程:
-
代码实现:
public int[] plusOne(int[] digits) {
int length = digits.length;
for (int index = length -1; index >= 0 ; index--){
if (digits[index] != 9 ){
digits[index]++;
return digits;
}else {
digits[index] =0;
}
}
int[] temp = new int[length+1];
temp[0] = 1;
return temp;
}