剑指 Offer 50. 第一个只出现一次的字符
题目说明
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
解题思路1:HashMap
使用传统的HashMap,对整一个数组进行遍历,更新记录每个字母的出现次数。在遍历结束之后重新遍历一遍数组,获取每个字母对应的取值。技巧是可以设置成为<Integer, Boolean>类型,出现第一次置为true,第二次乃至更多次都置为false
解题思路2:new int[26]
因为题目说明只有26个小写字母,那么我们可以用new int[26]的数组来当作HashMap使用,此后思路和思路1基本相同。但是这里不能用Boolean类型数组,因为即使字母没出现也要赋予一个值,那么就有三种状态了,用Boolean不再合适
解题思路3:LinkedHashMap
在Java中,使用LinkedHashMap可以实现有序哈希表
这道题目很明显对于顺序有一个要求,因此我们可以用LinkedHashMap来存储,这样在记录了次数的同时也维护了顺序性。此后就不用再去遍历一遍初始数组而是遍历LinkedHashMap来获取答案即可
剑指 Offer 11. 旋转数组的最小数字(第二次啦)
题目说明
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。
解题思路:二分查找
考虑数组中的最后一个元素x:在最小值右侧的元素都一定小于等于x,在最小值左侧的元素一定都大于等于x,可以利用该性质通过二分查找找出。
我们通过right处的值和mid处的值进行比较。可能有三种情况发生:
- numbers[right] > numbers[mid]:说明从mid到right是有序的,最小值有可能出现在mid处,将right更新为mid
- numbers[right] < numbers[mid]:说明波谷出现在mid + 1到right这一段,将left更新为mid
- numbers[right] < numbers[mid]:可能出现如下图所示的情况,此时无法确定波谷在mid到right这一段或者left到mid这一段,但可以肯定的是一定不会出现在high的位置,所以令high左移一步缩小范围
当循环结束时left=high,返回该位置的数字即可
剑指 Offer 53 - II. 0~n-1中缺失的数字
题目说明
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
解题思路
nums[i]
和i
有两种情况,分别是相等和nums[i] > i
,前者说明i
及左边没问题,后者说明i
右边没问题(但i
可能是有问题的)
跳出时,变量i
和j
分别指向 “右子数组的首位元素” 和 “左子数组的末位元素” 。因此返回i
即可。