剑指offer 53 - I. 在排序数组中查找数字I
统计一个数字在排序数组中出现的次数。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: 0
方法一:for循环判断数字出现的个数,如果重复出现,次数自增即可。
class Solution {
public int search(int[] nums, int target) {
//循环判断
int res = 0;
for(int i = 0; i < nums.length; i++ ){
if( nums[i] == target ){
res++;
}else if( nums[i] > target){
break;
}
}
return res;
}
}
方法二:二分查找,使用两次二分查找。第一次判断目标值第一次出现的位置,第二次判断目标值最后一次出现的位置。次数=尾-头+1
class Solution {
public int search(int[] nums, int target) {
if( nums.length == 0 ) return 0;
int l = 0, r = nums.length - 1;
//判断目标值右边界
while( l <= r){
int mid = l + (r - l) / 2;
if( nums[mid] <= target ){
l = mid + 1 ;
}else{
r = mid - 1;
}
}
if( r >= 0 && nums[r] != target ) return 0;
int e = r ;
//判断目标值左边界
l = 0;
r = nums.length - 1;
while( l <= r){
int mid = l + (r - l) / 2;
if( nums[mid] >= target ){
r = mid - 1;
}else{
l = mid + 1;
}
}
int b = l ;
return e - b + 1 ;
}
}
简化代码版本
class Solution {
public int search(int[] nums, int target) {
return binarySearch(nums,target) - binarySearch(nums,target - 1);
}
public int binarySearch(int[] nums , int tar){
int l = 0, r = nums.length - 1;
while( l <= r ){
int mid = l + ( r - l ) / 2;
if( nums[mid] <= tar) l = mid +1;
else r = mid -1 ;
}
return l;
}
}
剑指 Offer 53 - II. 0~n-1中缺失的数字
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
示例 1:
输入: [0,1,3]
输出: 2
示例 2:
输入: [0,1,2,3,4,5,6,7,9]
输出: 8
方法:循环
class Solution {
public int missingNumber(int[] nums) {
if( nums[0] == 1 ) return 0;
for( int i = 0; i < nums.length ; i++){
if( nums[i] != i ){
return nums[i] - 1 ;
}
}
return nums.length;
}
}
10.12 剑指 Offer 50. 第一个只出现一次的字符
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
示例 1:
输入:s = “abaccdeff”
输出:‘b’
示例 2:
输入:s = “”
输出:’ ’
方法:利用额外数组空间实现,遍历两遍,第一次统计每个字符出现的次数,第二次找出第一次只出现一次的字符。
class Solution {
public char firstUniqChar(String s) {
int[] a = new int[26];
char[] sc = s.toCharArray();
for(char ch : sc){
a[ ch - 'a' ]++;
}
for(char c : sc){
if( a[ c - 'a' ] == 1){
return c;
}
}
return ' ';
}
}