JS算法之数组中重复的数字及二维数组中的查找

1,602 阅读1分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

剑指Offer 03.数组中重复的数字

找出数组中重复的数字。

在一个长度为n的数组nums里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

 输入:
 [2, 3, 1, 0, 2, 5, 3]
 输出:23

限制:

2 <= n <= 100000

题解

法一 哈希表

通过题意,我们可以使用哈希表来实现,分析如下:

  1. 遍历数组,若当前数字不存在于哈希表,则添加到哈希表即可。
  2. 若当前数字哈希表中已存在,则返回结果。
 var findRepeatNumber = function(nums){
   let map = new Map();
   for(let i of nums){
     if(map.has(i)){
       return i;
     }
     map.set(i,1);
   }
   return null;
 }
  • 空间复杂度:O(n)

  • 时间复杂度:O(n)

法二 原地交换

剑指Offer中的解法,空间复杂度O(1) 时间复杂度O(n)

因为在一个长度为n点数组nums里的所有数字都在0~n-1的范围内,所以数组元素的索引一对多的关系,因此可以建立索引和值的映射,起到字典等价的作用。

Picture0.png

思路:

  1. 从头到尾依次扫描,如果当前项和下标不相等,则比较当前项和以当前项对应的下标的项是否相等,不相等则交换位置
  2. for循环中有一个while,但是由于每一项最多只会在while中交换两次,所以总体的时间复杂度仍然是O(n)
 var findRepeatNumber = function(nums) {
     for(let i = 0;i < nums.length;i++){
       let num = nums[i];
       while(num !== i){
         if(nums[i] === nums[num]){
           return num
         }
         nums[i] = nums[num]
         nums[num] = num
       }
     }
   return null
 };
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

剑指Offer 04.二维数组中的查找

二维数组中的查找

在一个n*m的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

🌰 现有矩阵matrix如下:

 [
   [1,   4,  7, 11, 15],
   [2,   5,  8, 12, 19],
   [3,   6,  9, 16, 22],
   [10, 13, 14, 17, 24],
   [18, 21, 23, 26, 30]
 ]

给定target = 5,返回true;给定target=20,返回false。

限制:0 <= n <= 1000; 0 <= m <= 1000

题解

法一 坐标轴法

根据题意知,二维数组从左往右递增,从上往下递增,则:

  • 某列的某个数字,该数之上的数字,都比其小;
  • 某行的某个数字,该数右侧的数字,都比其大;

所以,解题流程如下:

  1. 以二维数组左下角为原点,建立直角坐标轴。
  2. 若当前数字大于了查找数,查找往上移一位。
  3. 若当前数字小于了查找树,查找往右移一位。

如果target = 19,则路径为:18->21->13->14->17->24->22->19

 var findNumberIn2DArray = function(matrix,target){
   if(!matrix.length) return false;
   let x = matrix.length-1 , y = 0;
   while(x>=0 && y< matrix[0].length){
     if(matrix[x][y] === target){
       return true;
     }else if(matrix[x][y] > target){
       x--;
     }else{
       y++;
     }
   }
   return false;
 }

法二 数组降维法

将二维数组扁平化,再看其是否包含目标值。

 var findNumberIn2DArray = function(matrix,target){
   return matrix.flat(Infinity).includes(target);
 }