题:https://leetcode.com/problems/find-all-anagrams-in-a-string/
题目大意
对于数组int[] nums,其nums.length = n;
找出 i <=x <=n ,未出现在nums 中的元素。
要求 空间复杂度为 O(1);
思路
方法一 数组中 正负 为 出现标志
由于 数组中 均为 正数 且 只需要标识数的范围为 i <= y <=n ,可以直接用 数组对应的 下标位 nums[y-1] 标识 y 是否出现,若出现过 将 nums[y-1] 标识为负数。
这里需要注意的是,取出 的 y 应为 abs(nums[i]) ,因为可能之前标识过了。
class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
for(int num:nums){
if(nums[Math.abs(num) - 1] > 0)
nums[Math.abs(num) -1 ] = - nums[Math.abs(num) - 1];
}
List<Integer> res = new ArrayList();
for(int i = 0 ; i < nums.length ; i++)
if(nums[i] > 0)
res.add(i+1);
return res;
}
}
方法二 将 元素 放置对应位 作为 标识
由于 数组中 均为 正数 且 只需要标识数的范围为 i <= y <=n ,可以直接用 元素对应的位置 nums[y-1] 标识 y 是否出现,若出现过 将 nums[y-1] == y。
这里 用的方法是 交换。
将当前 元素 交换到 正确的位置,将交换的值作为当前元素再进行交换,直到 当前元素 x 与 nums[x] 相同。
这里要注意 交换操作,由于 两个数 获取时有依赖关系,当前元素的新值需要最后赋予。
class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
for(int i = 0 ; i < nums.length ;i++)
if(nums[i] != nums[nums[i] -1]){
int tmp = nums[nums[i] -1];
nums[nums[i] -1] = nums[i];
nums[i] = tmp;
i--;
}
List<Integer> res = new ArrayList();
for(int i = 0 ; i < nums.length; i++){
if(nums[i] != i+1)
res.add(i+1);
}
return res;
}
}