【每日算法】查找算法2(中等)

简介: 查找算法(中等)

16fb98eea012ef0cb446588ddc50662.png

题目

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

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。

示例:

输入:s = "abaccdeff"
输出:'b'
复制代码

分析一

思路从简单点的开始

使用正则匹配,对字符串从前往后遍历,只要匹配结果出现唯一个值的,就是我们所找的第一个只出现一次的字符,直接返回即可

实现

function firstUniqChar(s: string): string {
    for (let i of s) {
        const reg = new RegExp(i, "g")
        if (s.match(reg).length === 1) {
            return i
        }
    }
    return ' '
};
复制代码

分析二

上面的解法实际上每一次都对整个字符串做全量匹配,现在我们来进行一下优化,看能不能减少遍历次数

一般时间优化都会想到使用哈希表来空间换时间,那么

  • 我们在遍历的时候将每个字符作为key存入哈希表中,遇到相同字符时,将对应的key值加一
  • 得到哈希表后,我们在对哈希表进行一次遍历(哈希表存值是有序的),找到第一个key值为1的位置,将key返回,即得到我们所求的结果
  • 如果没有找到,按照题意返回空字符串

实现

function firstUniqChar(s: string): string {
    let map: Map<string, number> = new Map()
    for(let i of s) {
        if (map.get(i)) {
            map.set(i, map.get(i) + 1)
        } else {
            map.set(i, 1)
        }
    }
    for (let [ key, value ] of map.entries()) {
        if (value === 1) {
            return key
        }
    }
    return ' '
};
复制代码

分析三

由于上述方法使用了map的迭代,可以考虑将 key 值换成 boolean 值来对逻辑进行一下优化,在判断的时候更加简洁直观点

实现

function firstUniqChar(s: string): string {
    let map: Map<string, boolean> = new Map()
    for (let key of s) {
        if (map.has(key)) {
            map.set(key, false)
        } else {
            map.set(key, true)
        }
    }
    for (let key of s) {
        if (map.get(key)) {
            return key
        }
    }
    return ' '
};
复制代码

题目

剑指 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]
]
复制代码

分析一

本题有一定难度,我们先用暴力破解+二分查找的方法把答案做出来先

  • 遍历每一层数组
  • 在数组内部使用二分查找
  • 如果碰到目标值,返回 true
  • 循环结束没有遇到目标值,返回 false

实现

function findNumberIn2DArray(matrix: number[][], target: number): boolean {
    for (let i = 0; i < matrix.length; i ++) {
        let left = -1
        let right = matrix[i].length
        while(left + 1 != right) {
            const mid = (left + right) >> 1
            if (matrix[i][mid] === target) {
                return true
            } else if (matrix[i][mid] > target) {
                right = mid
            } else {
                left = mid
            }
        }
    }
    return false
};
复制代码

分析二

利用该二维数组的特性,从右上角开始遍历

  • 如果目标值大于右上角,那么目标值只可能在当前 y 轴上,j ++ 从上往下遍历
  • 如果目标值小于右上角,么 x 轴先退一列,i -- ,后续在从上往下遍历
  • 如果相等,返回 true

实现

function findNumberIn2DArray(matrix: number[][], target: number): boolean {
    let i = matrix.length-1
    let j = 0
    while( i>=0 && j <=matrix[0].length -1){
        if(matrix[i][j]>target){
            i--
        }else if(matrix[i][j] <target){
            j++
        }else return true
    }
    return false
};
相关文章
|
4月前
|
算法
【算法】二分算法——点名
【算法】二分算法——点名
|
2月前
|
算法 Java 索引
数据结构与算法学习十五:常用查找算法介绍,线性排序、二分查找(折半查找)算法、差值查找算法、斐波那契(黄金分割法)查找算法
四种常用的查找算法:顺序查找、二分查找(折半查找)、插值查找和斐波那契查找,并提供了Java语言的实现代码和测试结果。
33 0
|
7月前
|
算法
DAY-7 | 牛客-BM21 寻找旋转数组的最小元素:二分法分治思想真的很可靠
这是一个关于编程题目的摘要:题目是牛客网上的&quot;BM21 旋转数组的最小数字&quot;,要求找到旋转数组中的最小数字。题解介绍了使用二分查找算法来解决此问题,因为其时间复杂度优于暴力搜索的线性时间复杂度。二分查找的核心是通过比较中间元素与右端元素的大小,不断缩小搜索范围,最终找到最小值。代码示例展示了如何实现这个算法。总结中强调了二分查找适用于部分有序数组,并指出了解决这类问题的关键在于理解数组的二段单调性。
48 1
|
7月前
|
算法 前端开发 JavaScript
< 每日算法:一文带你认识 “ 双指针算法 ” >
`双指针`并非指的是一种具体的公式或者范式。而是一种运算思路,用于节省逻辑运算时间的`逻辑思路`!双指针算法通常用于`优化时间复杂度`!
< 每日算法:一文带你认识 “ 双指针算法 ” >
|
算法 C++ Python
每日算法系列【LeetCode 556】下一个更大元素 III
每日算法系列【LeetCode 556】下一个更大元素 III
|
算法 C++ Python
每日算法系列【LeetCode 503】下一个更大元素 II
每日算法系列【LeetCode 503】下一个更大元素 II
|
算法 C++ Python
每日算法系列【LeetCode 16】最接近的三数之和
每日算法系列【LeetCode 16】最接近的三数之和
|
人工智能 算法 BI
【每日算法Day 97】经典面试题:求两个数组最小差
【每日算法Day 97】经典面试题:求两个数组最小差
141 0
|
缓存 NoSQL 算法
一日一技:二分偏左,二分搜索在分布式系统里面也有用?
一日一技:二分偏左,二分搜索在分布式系统里面也有用?
97 0