¶剑指offer – 查找算法
¶剑指 Offer 03. 数组中重复的数字
Difficulty: 简单
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
1 | 输入: |
限制:
2 <= n <= 100000
Solution
方法一:计数方法
1 | class Solution { |
时间复杂度:$O(N)$,一次遍历
空间复杂度:$O(N)$, res 数组占用额外空间
方法二:原地交换
1 | class Solution { |
时间复杂度:$O(N)$,一次遍历
空间复杂度:$O(1)$, 原地操作,无额外空间消耗。
方法三:替换法
1 | class Solution { |
时间复杂度:$O(N)$,一次遍历
空间复杂度:$O(1)$, 原地操作,无额外空间消耗。
注意:方法二,只能返回随机一个重复值(排列中最靠前的那个重复数字),方法一,方法三可以返回第一个(最小)重复值。
¶剑指 Offer 04. 二维数组中的查找
Difficulty: 中等
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
现有矩阵 matrix 如下:
1 | [ |
给定 target = 5
,返回 true
。
给定 target = 20
,返回 false
。
限制:
0 <= n <= 1000
0 <= m <= 1000
Solution
1 | class Solution { |
时间复杂度:$O(N + M)$,其中,N 和 M 分别为矩阵行数和列数,此算法最多循环M+N 次。
空间复杂度:$O(1)$,只需要 i, j 两个变量即可。
¶剑指 Offer 11. 旋转数组的最小数字
Difficulty: 简单
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2]
为 [1,2,3,4,5]
的一个旋转,该数组的最小值为1。
示例 1:
1 | 输入:[3,4,5,1,2] |
示例 2:
1 | 输入:[2,2,2,0,1] |
Solution
方法一:排序
1 | class Solution { |
时间空间复杂度基于排序算法的时间空间复杂度。
方法二:一次遍历
1 | class Solution { |
时间复杂度:$O(N)$,N为数组长度
空间复杂度:$O(1)$,无额外空间消耗
方法三:二分查找
1 | class Solution { |
时间复杂度:$O(\log N)$
**空间复杂度:**只需要 i,j,m 变量即可
¶剑指 Offer 50. 第一个只出现一次的字符
Difficulty: 简单
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
示例:
1 | s = "abaccdeff" |
限制:
0 <= s 的长度 <= 50000
Solution
方法一:哈希表
1 | class Solution { |
时间复杂度:$O(N)$,N 为数组长度
空间复杂度:$O(1)$,最多 26 个字符
方法二:哈希表优化
1 | class Solution { |
时间和空间复杂度均与 “方法一” 相同,而具体分析:方法一 需遍历 s
两轮;方法二 遍历 s
一轮,遍历 keys
一轮( dic, keys
的长度都不大于 26 )。空间上,方法二多了 keys
,但是其长度最大为 26;
¶剑指 Offer 53 - I. 在排序数组中查找数字 I
Difficulty: 简单
统计一个数字在排序数组中出现的次数。
示例 1:
1 | 输入: nums = [5,7,7,8,8,10], target = 8 |
示例 2:
1 | 输入: nums = [5,7,7,8,8,10], target = 6 |
限制:
0 <= 数组长度 <= 50000
Solution
方法一:哈希表
1 | class Solution { |
时间复杂度:$O(N)$,N 为数组长度,一次遍历构建哈希表。
空间复杂度:$O(N)$,哈希表所占额外空间。
方法二:二分查找
1 | class Solution { |
时间复杂度:$O(\log N)$,N 为数组长度。
空间复杂度:$O(1)$,left, right, mid, count 几个变量所需的额外空间。
¶剑指 Offer 53 - II. 0~n-1中缺失的数字
Difficulty: 简单
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
示例 1:
1 | 输入: [0,1,3] |
示例 2:
1 | 输入: [0,1,2,3,4,5,6,7,9] |
限制:
1 <= 数组长度 <= 10000
Solution
方法一:一次遍历
1 | class Solution { |
时间复杂度:$O(N)$,N 为数组长度
空间复杂度:$O(1)$,无需额外空间
方法二:二分查找
**注意:**看个人喜好选择自己更容易理解的版本,本人更倾向版本二。
1 | class Solution { |
1 | class Solution { |
时间复杂度:$O(\log N)$,N 为数组长度。
空间复杂度:$O(1)$,left, right, mid 几个变量所需的额外空间。
¶参考资料
图解算法数据结构 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台 (leetcode-cn.com)