- 复习JavaScript中Object的使用。js系列-Object对象_js object_前端蜗牛君的博客-CSDN博客
- 复习JavaScript中Map的使用。Javascript Map.entries( )实例讲解 - 码农教程 JavaScript -- Map对象及常用方法介绍_javascript map撖寡情_Hydrion-Qlz的博客-CSDN博客
- js中运算符in和of的区别 https://knife.blog.csdn.net/article/details/126714506
题目:645. 错误的集合
我的思路:先将数组排序,然后将nums[j]与该位置上正确的数i比较,如果nums[j]=i+1,则说明此处有个数字缺失(缺失的数为i),并立刻将i++;如果nums[j]=i-1,则说明此处是重复的数字(重复数为i-1),并立刻i--。
遍历后有两种特殊情况需要讨论:缺失值在最后(即缺失值undefined),1缺失2重复(即重复值undefined)。
/**
* @param {number[]} nums
* @return {number[]}
*/
var findErrorNums = function(nums) {
nums.sort( (a,b) => a-b );
var a,b;
for (let i=1,j=0; j<nums.length; i++,j++) {
if(i == nums[j]){
continue;
}else if(i+1 == nums[j]){
b=i;
i++;
}else if(i-1 == nums[j]){
a=i-1;
i--;
}
}
if(b == undefined) b=nums.length;
if(a == undefined) a=2;
return [a,b];
};
题解的方法一:先排序,将数组前后两个数比较,相等为重复的数,相减大于1为缺失数。需要对缺失值为1和n进行讨论。
方法二:用哈希表记录元素出现的次数
var findErrorNums = function(nums) {
const errorNums = new Array(2).fill(0);
const n = nums.length;
const map = new Map();
for (const num of nums) {
map.set(num, (map.get(num) || 0) + 1);
}
for (let i = 1; i <= n; i++) {
const count = map.get(i) || 0;
if (count === 2) {
errorNums[0] = i;
} else if (count === 0) {
errorNums[1] = i;
}
}
return errorNums;
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/set-mismatch/solution/cuo-wu-de-ji-he-by-leetcode-solution-1ea4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
时间复杂度和空间复杂度都为O(n)
方法三:纯数学方法
class Solution:
def findErrorNums(self, nums):
ln, total = len(nums), sum(set(nums))
return [sum(nums) - total, (1 + ln) * ln // 2 - total]
题目:697. 数组的度
我的思路:容易想到,首先统计各个元素出现的频次,最短连续子数组必定一头一尾是频次最大的那个数,需要比较频次最大且相等的不同元素的子数组的长度。
但是,我将上面的步骤拆分了来做,复杂且没有结果。
看看官方题解:
在实际代码中,我们使用哈希表实现该功能,每一个数映射到一个长度为 3 的数组,数组中的三个元素分别代表这个数出现的次数、这个数在原数组中第一次出现的位置和这个数在原数组中最后一次出现的位置。当我们记录完所有信息后,我们需要遍历该哈希表,找到元素出现次数最多,且前后位置差最小的数。
var findShortestSubArray = function(nums) {
const mp = {};
for (const [i, num] of nums.entries()) {
if (num in mp) {
mp[num][0]++;
mp[num][2] = i;
} else {
mp[num] = [1, i, i];
}
}
let maxNum = 0, minLen = 0;
for (const [count, left, right] of Object.values(mp)) {
if (maxNum < count) {
maxNum = count;
minLen = right - left + 1;
} else if (maxNum === count) {
if (minLen > (right - left + 1)) {
minLen = right - left + 1;
}
}
}
return minLen;
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/degree-of-an-array/solution/shu-zu-de-du-by-leetcode-solution-ig97/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
时间复杂度O(n)
空间复杂度O(n)
滑窗解法:
//时间O(n) 空间O(n)
class Solution {
public int findShortestSubArray(int[] nums) {
int n = nums.length;
int[] freq = new int[50000];//记录频数
int degree = 0;//记录数组度
for (int i = 0; i < n; i++) {
degree = Math.max(++freq[nums[i]], degree);
}
Arrays.fill(freq, 0);
int left = 0, right = 0, minSpan = Integer.MAX_VALUE;//窗口边界和最小跨度
while (right < n) {
freq[nums[right]]++;//右窗口划进一个数,其频数加一
while (left <= right && degree == freq[nums[right]]) {//如果其频数等于度
minSpan = Math.min(minSpan, right - left + 1);//记录最小窗口大小
freq[nums[left++]]--;//收缩左窗口
}
++right;//扩大右窗口
}
return minSpan;
}
}
通过建立哈希表,再遍历的方法容易想到,但不满足原地算法。
题解:
var findDisappearedNumbers = function(nums) {
const n = nums.length;
for (const num of nums) {
const x = (num - 1) % n;
nums[x] += n;
}
const ret = [];
for (const [i, num] of nums.entries()) {
if (num <= n) {
ret.push(i + 1);
}
}
return ret;
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/find-all-numbers-disappeared-in-an-array/solution/zhao-dao-suo-you-shu-zu-zhong-xiao-shi-d-mabl/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
同样要求原地算法,可以用上一题的方法解(+n,%n)
方法二:将元素交换到对应的位置
方法三:用正负号标记
(三种原地方法都包含了对应关系:nums[i] - 1 -> 位置i )
由上题方法二想到解法,将数组复原到元素拜访到对应位置的状态。但此题中需要注意:在完成交换后,新的 nums[i] 可能还在 [1,N] 的范围内,我们需要继续进行交换操作,所以需要使用while而不是if。
/**
* @param {number[]} nums
* @return {number}
*/
var firstMissingPositive = function(nums) {
var temp;
var swap = function(nums, a, b){
temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
for(let i=0; i<nums.length; i++){
while(nums[i]>0 && nums[i]<=nums.length && nums[i] != nums[nums[i]-1]){
swap(nums, i, nums[i]-1);
}
}
for(let i=0; i<nums.length; i++){
if (nums[i] != i+1) return i+1;
}
return nums.length+1;
};
此题用正负号标记也可以完成: