刷题计划(第4天)
时间:2022.4.20
题数:3
题目类型:查找&二分&哈希&字符串
1. 二维数组中的查找
找出数组中重复的数字。在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
从二维数组的右上角开始遍历,当大于target向左移动,小于target向下移动
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
if(matrix.size()==0){
return false;
}
int m=matrix.size(),n=matrix[0].size();
int row=0,col=n-1;
while(row<m&&col>=0){
if(matrix[row][col]>target){
col--;
}else if(matrix[row][col]<target){
row++;
}else{
return true;
}
}
return false;
}
};
当然也可以使用二分法毕竟有序
2.第一个只出现一次的字符
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。
注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。
看到一半一半有序,明显采用二分法,如下:
class Solution {
public:
int minArray(vector<int>& numbers) {
int n=numbers.size();
int left=0,right=n-1;
while(left<right){
int mid=(right-left)/2+left;
if(numbers[mid]<numbers[right]){
right=mid;
}else if(numbers[mid]>numbers[right]){
left=mid+1;
}else{
while(numbers[right]==numbers[mid]&&right!=mid){//处理重复的元素
right--;
}
}
}
return numbers[left];
}
};
和昨天的二分查找类似
3. 第一个只出现一次的字符
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
经典空间换时间
class Solution {
public:
char firstUniqChar(string s) {
if(s.empty()){
return ' ';
}
int table[26]={0};
for(char c:s){
table[c-'a']++;
}
for(char c:s){
if(table[c-'a']==1) return c;
}
return ' ';
}
};
总结
算是前面的复习