学习目标:
本次学习目标为 力扣初级算法-数组,其中主要的LC如下:
- 存在重复元素
- 只出现一次的数字
学习内容:
- 旋转数组 (链接)
给定一个整数数组,判断是否存在重复元素。
如果存在一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false示例1:
输入: [1,2,3,1]
输出: true示例2:
输入: [1,2,3,4]
输出: false示例3:
输入: [1,1,1,3,3,4,3,2,4,2]
输出: true
解题思路:
- 解法一: 排序后比较
- 边界问题:空数组和null 问题
- 代码逻辑过程:
- 先对入参数组排序
- 再对入参数组中的相邻元素做比较
- 代码实现:
public boolean containsDuplicate01(int[] nums) {
Arrays.sort(nums);
for (int index = 1; index < nums.length; index ++){
if (nums[index] == nums[index-1]){
return true;
}
}
return false;
}
- 解法二:Set集合去重
- 边界问题:空数组和null 问题
- 代码逻辑过程:
- 声明Set 集合对象,用于存放已判断多的元素
- 循环遍历入参数组,直接将元素放入 Set集合中
- 当 Set集合 已存在当前元素,将会直接返回 false, 并跳出当前循环;
- 当 Set集合 不存在当前元素,将会直接返回 true,同时进入下一个循环。
- 代码实现:
public static boolean containsDuplicate02(int[] nums) {
Set<Integer> set = new HashSet<>();
for (int num : nums) {
if (!set.add(num)) {
return true;
}
}
return false;
}
- 只出现一次的数字 (链接)
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?示例1:
输入: [2,2,1]
输出: 1示例2:
输入: [4,1,2,1,2]
输出: 4
- 解法一:位运算解决
- 边界问题:空数组和null 问题
- 解题思路:
- 条件是只有一个元素出现一次,其余均出现两次,故可根据位运算的逻辑特性,对入参数组的所有元素做位运算,最后返回的结果即为我们想要的结果。
- 代码逻辑过程:
- 循环遍历数组,将所有元素进行位运算
- 最后得出的结果即为 只出现过一次的元素
- 代码实现:
public int singleNumber01(int[] nums) {
int result = 0;
for (int num : nums) result ^= num;
return result;
}
- 解法二:Set集合解决
- 边界问题:空数组和null 问题
- 解题思路:
- 根据 Set 集合的唯一性,可直接将元素放入 Set中,当 Set 存在已有元素时,则会存入失败,此时再讲元素从 Set中移除,则最后 Set集合存在的元素为再入参数组中只出现过一次的元素。
- 代码逻辑过程:
- 循环遍历数组,将元素存入 Set 集合中
- 当存入 Set集合失败时,则再将此元素从 Set集合中移除
- 最后存在于 Set集合中的元素则为只出现过一次的元素。
- 循环遍历数组,将元素存入 Set 集合中
- 代码实现:
public int singleNumber02(int[] nums) {
Set<Integer> set =new HashSet<>();
for (int num : nums) {
if (!set.add(num)){
set.remove(num);
}
}
return (int) set.toArray()[0];
}
学习笔记:
- 位运算规律
1^1=0;
1^0=1;
0^1=1;
0^0=0;
- Set 集合的特性
- 元素是无序,元素不可以重复
- HashSet:实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set的迭代顺序;特别是它不保证该顺序恒久不变,此类允许使用null元素。
- TreeSet:使用元素的自然顺序对元素进行排序
- LinkedHashSet:使用链表维护了一个添加进集合中的顺序。导致当我们遍历LinkedHashSet集合元素时,是按照添加进去的顺序遍历的!