文章目录
(LeetCode 1)两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。
方法一 暴力解决
暴力解决,从头到尾遍历数组,找出相加符合目标值的两值
- 问题已理解
如果面试遇到不会的,暴力解决也不失为一种办法,1总比0好,可能在叙述暴力解决办法的过程中就发现了可以改进的地方。
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
for(int i = 0;i < nums.length;i++){
for(int j = i + 1;j < nums.length;j++){
if(nums[i]+nums[j] == target){
result[0] = i;
result[1] = j;
return result;
}
}
}
return result;
}
方法一 改进
依旧是使用HashMap,遍历第一个数时,在Map里找它相加等于目标值的值,没有就将它添加进去;再遍历第二个值,这样,只遍历数组一次就解决了问题。
- 问题已理解
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> storeNums = new HashMap<>(nums.length,1);
//这里的第一个参数nums.length表示该HashMap对象的初始容量,
//第二个参数1表示哈希表的负载因子,即哈希表在达到负载因子时会自动扩容。
int[] result = new int[2];
for(int i = 0;i < nums.length;i++){
int another = target - nums[i];
//该Map的键值对是index为值,value是键
Integer anotherIndex = storeNums.get(another);
//找到就返回下标
if(null != anotherIndex){
result[0] = anotherIndex;
result[1] = i;
break;
}else{
//没找到就返回遍历到的数和对应下标
storeNums.put(nums[i],i);
}
}
return result;
}
(LeetCode 88)合并两个有序数组
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2
的元素数目。 请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m
个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
方法一 先合并再排序
先合并再排序,但这样破坏了原有的顺序
public void merge(int[] nums1, int m, int[] nums2, int n) {
for(int i = 0;i < n;++i){
nums1[m+i] = nums2[i];
}
Arrays.sort(nums1);
}
方法二 从后往前比较元素大小
为了不破坏原有的顺序,我们可以从后往前比较俩数组元素的大小,大的放在nums1的后面的位置
- 问题已理解
public void merge(int[] nums1, int m, int[] nums2, int n) {
int p = m + n - 1;
int p1 = m - 1;
int p2 = n - 1;
while(p1 >= 0 && p2 >= 0){
if(nums1[p1] >= nums2[p2]){
nums1[p] = nums1[p1];
p1--;
}else{
nums1[p] = nums2[p2];
p2--;
}
p--;
}
while(p2 >= 0){
//nums1已经取完,直接取nums2
nums1[p] = nums2[p2];
p2--;
p--;
}
}
(LeetCode 283)移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作
方法 非零在前,零在后
遍历数组,遇到非零的数字按顺序添加在数组前面,并记录个数;数组遍历完后,直接将数组剩下的位置的元素赋值成0
- 问题已理解
public void moveZeroes(int[] nums) {
if(nums == null){
return;
}
//第一次遍历,j记录非0的个数,只要遍历过程中遇到非零的数,就赋给nums[j]
int j = 0;
for(int i = 0;i <nums.length;i++){
if(nums[i]!=0){
nums[j++] = nums[i];
}
}
//第二次遍历将剩下队尾的元素全赋值成0
for(int i = j;i<nums.length;i++){
nums[i] = 0;
}
}
(LeetCode 448)找到数组中消失的数字
给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。
在不使用额外空间且时间复杂度为 O(n) 的情况下解决这个问题
方法 遍历修改元素,看最后没被修改的元素位置
遍历数组,根据数组元素的 值-1 找到对应位置上的元素,加上n(或>=n)值。
总之就是把数组元素的值看成对应的位置,修改对应位置的元素,且能让机器识别出来确实是修改后的数据(如大于某一值),然后遍历数组元素,找出没被修改的元素,位置+1(+ -1是因为数组从0开始计数)
- 问题已理解
public List<Integer> findDisappearedNumbers(int[] nums) {
int n = nums.length;
for(int num:nums){
int x = (num - 1) % n;
nums[x] += n;
}
List<Integer> result = new ArrayList<Integer>();
for(int i = 0;i < n;i++){
if(nums[i] <= n){
result.add(i + 1);
}
}
return result;
}