重复相关
1. 删除排序数组的重复项
这个主要要求原地删除,不使用额外的数组空间,使用O(1)的额外空间
这个题主要可以用双指针法来确定。一个用于遍历数组,记为i;另一个用于记录不重复数组的最后的位置,记为count;其中count和i相互操作用于替换
即:
1 2 2 3 4
count i
比较的是count-1和 i
1 | public int removeDuplicates(int[] nums) { |
第六个也是用的双指针
2. 存在重复元素
方法一:先排序,然后再查找重复元素
1
2
3
4
5
6
7
8
9public boolean containsDuplicate(int[] nums) {
Arrays.sort(nums);
for (int i = 0; i < nums.length; i ++){
if (nums[i] == nums[i + 1]){
return true;
}
}
return false;
}方法二:利用Set集合的不重复性来实现查找重复元素
1
2
3
4
5
6
7
8
9
10public boolean containsDuplicate(int[] nums) {
Set<Integer> set = new HashSet<>(nums.length);
for(int num: nums){
if (set.contains(num)){
return true;
}
set.add(num);
}
return false;
}
3. 只出现一次的数字
可以利用异或的特性:
- 1 ^ 1 = 0
- 0 ^ 1 = 1
1 | public int singleNumber(int[] nums) { |
4. 买股票的最佳时机 贰
其实就是问的两数之差的和的最大值,其中,大的数要在小的数后面
1 | public int maxProfit(int[] prices) { |
数组移动相关
5. 旋转数组
1 | public void rotate(int[] nums, int k) { |
6. 移动零
需要2个指针,第一个指向0(需要不断检测),第二个指向非0
- 0 1 0 3 12
i j - 1 0 0 3 12
i j
- 1 3 0 0 12
i j
1 | public void moveZeroes(int[] nums) { |
7. 加一
有三种情况:
$$
123 \rightarrow 124
$$$$
1299 \rightarrow 1300
$$$$
999 \rightarrow 1000
$$
1 | public int[] plusOne(int[] digits) { |
两个数组
8. 两个数组的交集 贰
正常来说,这个题能想到的有两种方法:
用map存第一个数组,然后拿出来和第二个数组比对
先排序,然后用双指针
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public int[] intersect(int[] nums1, int[] nums2) {
int [] outTemp = new int[nums1.length > nums2.length ? nums2.length : nums1.length];
int temp = 0;
Arrays.sort(nums1);
Arrays.sort(nums2);
for (int i1 = 0, i2 = 0; i1 < nums1.length && i2 < nums2.length;){
if (nums1[i1] == nums2[i2]){
outTemp[temp ++] = nums1[i1];
i2 ++;
i1 ++;
} else if (nums1[i1] > nums2[i2]){
i2 ++;
} else if (nums1[i1] < nums2[i2]){
i1 ++;
}
}
return Arrays.copyOfRange(outTemp, 0, temp);
}
9. 两数之和
这个题比较巧的就是用了map,譬如
nums = 2,7,8,12 target = 9
我们要注意:9 - 7 = 2 ,同时 9 - 2 = 7
1 | public int[] twoSum(int[] nums, int target) { |
二维数组
10. 有效的数独
这道题比较秀的一点是,它利用了三个set来存放row,column和box,同时9个box的索引可以通过(row / 3 ) * 3 + column / 3
1 | public boolean isValidSudoku(char[][] board) { |
11. 旋转图像
这道题用到了 转置 + 翻转 的线性代数中的特性
$$
[
[1,2,3],
[4,5,6],
[7,8,9]
]
\rightarrow
[
[1,4,7],
[2,5,8],
[3,6,9]
]
\rightarrow
[
[7,4,1],
[8,5,2],
[9,6,3]
]
$$
1 | public void rotate(int[][] matrix) { |