加载中...

[leetcode]第 5 天 查找算法(中等)

04. 二维数组中的查找

思路

直接遍历!两个for循环

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        for(int[] row : matrix){
            for(int e : row){
                if(e == target) return true;
            }
        }
        return false;
    }
}

很显然不够优雅,且时间复杂度为O(NM)。。看看有没有更好的解法。。

大佬提供了标志数法。就是将矩阵旋转45°,类似于二叉搜索树,因此从根节点开始搜索,遇到比target大的元素就向左,反之向右。
以matrix左下角元素为标志数flag

  1. flag > target,则target在flag所在行上方,消去flag所在行
  2. flag < target,则target在flag所在列右方,消去flag所在列

流程:

  1. 从(i, j)开始遍历
    若matrix[i][j] > target,i--
    若matrix[i][j] < target,j++
    若matrix[i][j] = target,返回true
  2. 索引越界,返回false
    时间复杂度O(M+N)
class Solution{
  public boolean findNumberIn2DArray(int[][] matrix, int target){
    int i = matrix.length - 1, j = 0;
    while(i >= 0 && j < matrix[0].length){
       if(matrix[i][j] > target) i--;
       else if(matrix[i][j] < target) j++;
       else return true;
    }
    return false;
  }
}

11. 旋转数组的最小数字

思路

经过两小时的历练我还是选择了循环。。。

class Solution {
    public int minArray(int[] numbers) {
        int a = numbers[0];
        for(int i = numbers.length - 1 ; i >= 0; i--){
            if(a > numbers[i]) a = numbers[i];
        }
        return a;
    }
}

很明显不够优雅,评论区给了二分法的解法。
原来在旋转数组里也可以使用二分查找吗><!
流程还是三部曲:

  1. 初始化
    i, j分别指向数组的左右两端
  2. 循环二分
    m = (i + j)/2;
  3. nums[m] > nums[j],m在左子组中,旋转点x在[m + 1, j] 中, i = m + 1;
  4. nums[m] < nums[j],m在右子组中,旋转点x在[i, m - 1] 中, j = m;
  5. nums[m] = nums[j],无法判断旋转点在哪,因为可能是[2, 2, 0, 1, 2],所以j = j - 1;
  6. 返回值:i = j时跳出循环,返回nums[i]
class Solution {
    public int minArray(int[] numbers) {
        int i = 0, j = numbers.length - 1;
        while (i < j) {
            int m = (i + j) / 2;
            if (numbers[m] > numbers[j]) i = m + 1;
            else if (numbers[m] < numbers[j]) j = m;
            else j--;
        }
        return numbers[i];
    }
}

50. 第一个只出现一次的字符

思路

用hashMap存储字符和是否重复出现的标志。

class Solution {
    public char firstUniqChar(String s) {
        Map<Character, Boolean> strMap = new HashMap<>();
        char[] ch = s.toCharArray();
        for(char c : ch){
            strMap.put(c, !strMap.containsKey(c));
        }
        for(char c : ch){
            if(strMap.get(c)) return c;
        }
        return ' ';
    }
}
posted @ 2022-12-21 13:30  Vincy9501  阅读(12)  评论(0编辑  收藏  举报