645. 错误的集合

思路

本质上就是一个数学问题,
(原数组的和-去掉重复的数据的数组和)=重复的数字
(从1到数组的长度length的数据的和(1+2+…+length))-(去掉重复的数据的数组和)=缺失的数字

代码

  1. /**
  2. * @param {number[]} nums
  3. * @return {number[]}
  4. */
  5. var findErrorNums = function(nums) {
  6. let a = getSum(nums) - getSum([...new Set(nums)])
  7. let b = calcSum(nums.length) - getSum([...new Set(nums)])
  8. return [a, b]
  9. };
  10. function getSum(arr) {
  11. let sum = 0;
  12. for(let i = 0; i < arr.length; i ++) {
  13. sum += arr[i]
  14. }
  15. return sum;
  16. }
  17. function calcSum(n) {
  18. let sum = 0;
  19. for(let i = 1; i <= n; i ++) {
  20. sum += i;
  21. }
  22. return sum;
  23. }

复杂度分析

时间复杂度 统计数组中的元素 - 图1#card=math&code=O%28N%29)
空间复杂度 统计数组中的元素 - 图2#card=math&code=O%281%29)

697. 数组的度

思路

理解题意:先找众数,如果只有1个则返回众数的个数,如果有多个,则返回区间最小的长度。

先用map存储数字的总数和下标;
经过两次遍历,得到结果

代码

  1. /**
  2. * @param {number[]} nums
  3. * @return {number}
  4. */
  5. var findShortestSubArray = function(nums) {
  6. const map = {};
  7. for(let i = 0; i < nums.length; i ++) {
  8. let cur = nums[i];
  9. if (map[cur]) {
  10. map[cur].count += 1;
  11. if (map[cur].idxs.length > 1) {
  12. map[cur]['idxs'][1] = i
  13. } else {
  14. map[cur].idxs.push(i);
  15. }
  16. } else {
  17. map[cur] = {
  18. count : 1,
  19. idxs: [i]
  20. }
  21. }
  22. }
  23. let max = 0, keys = []
  24. for(let [key, {count}] of Object.entries(map)) {
  25. if (count > max) {
  26. max = count
  27. keys = [key]
  28. } else if (count == max) {
  29. keys.push(key)
  30. }
  31. }
  32. if (keys.length == 1) {
  33. let [start, end] = map[keys[0]].idxs
  34. return end ? (end - start + 1) : 1
  35. }
  36. let ret = nums.length;
  37. for(let key of keys) {
  38. let {count, idxs:[start, end]} = map[key]
  39. ret = Math.min(ret, end ? (end - start + 1) : 1)
  40. }
  41. return ret;
  42. };

复杂度分析

时间复杂度 统计数组中的元素 - 图3#card=math&code=O%28N%29)
空间复杂度 统计数组中的元素 - 图4#card=math&code=O%28N%29)

448. 找到所有数组中消失的数字

思路

创建一个长度为n+1长度的结果数组;

第一次遍历将存在的数字对应坐标上赋值;

第二次对结果数组取反,将空位上赋值为当前的idx,为缺失的数字;

然后对结果数组过滤掉空值;

代码

  1. /**
  2. * @param {number[]} nums
  3. * @return {number[]}
  4. */
  5. var findDisappearedNumbers = function(nums) {
  6. let res = []
  7. for(let i = 0; i < nums.length; i ++) {
  8. let cur = nums[i];
  9. res[cur] = 1;
  10. }
  11. for(let i = 1; i <= nums.length;i++) {
  12. let cur = res[i];
  13. if (cur) {
  14. res[i] = undefined
  15. } else {
  16. res[i] = i;
  17. }
  18. }
  19. return res.filter(Boolean);
  20. };

复杂度分析

时间复杂度 统计数组中的元素 - 图5#card=math&code=O%28N%29)
空间复杂度 统计数组中的元素 - 图6#card=math&code=O%281%29)

442. 数组中重复的数据

思路

由于索引和对应值有关系,第1次出现可以将当前值对应的索引位置的值取反,当第二次遍历到该值索引时为负数。

eg: [1,2,3,4,5,2]

第一次遍历

[1,2,3,4,5] => [-1, -2, -3, -4, -5]

第二次遍历

[-1, -2, -3, -4, -5] => [-1, 2, -3, -4, -5]

代码

  1. /**
  2. * @param {number[]} nums
  3. * @return {number[]}
  4. */
  5. var findDuplicates = function(nums) {
  6. const res = [];
  7. for(let i = 0; i < nums.length; i ++) {
  8. let cur = Math.abs(nums[i]);
  9. if (nums[cur-1] > 0) {
  10. nums[cur-1] *= -1
  11. } else {
  12. res.push(cur)
  13. }
  14. }
  15. return res;
  16. };

复杂度分析

时间复杂度 统计数组中的元素 - 图7#card=math&code=O%28N%29)
空间复杂度 统计数组中的元素 - 图8#card=math&code=O%281%29)

274. H 指数

思路

默认h为文章数,对引用量排序,如果小于h,将h—

代码

/**
 * @param {number[]} citations
 * @return {number}
 */
var hIndex = function(citations) {
  citations = citations.sort((a, b) => a - b);
  let len = citations.length, res = len;
  for(let i = 0; i < len; i ++) {
    let cur = citations[i];
    if (cur < res) {
      res -= 1;
    }
  }
  return res;
};

复杂度分析

时间复杂度 统计数组中的元素 - 图9#card=math&code=O%28nlogN%29)
空间复杂度 统计数组中的元素 - 图10#card=math&code=O%281%29)

41. 缺失的第一个正数