力扣初级算法-04-数组-两个数组的交集 II、加一

学习目标:

本次学习目标为 力扣初级算法-数组,其中主要的LC如下:

  • 两个数组的交集 II
  • 加一

学习内容:

  1. 两个数组的交集 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;
	}
  1. 只出现一次的数字 (链接)
    给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
    最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
    你可以假设除了整数 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;
	}

学习笔记:

你可能感兴趣的:(算法,力扣,算法,leetcode,排序算法)