剑指offer day5

70 阅读1分钟

刷题计划(第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;
    }
};

image.png

当然也可以使用二分法毕竟有序

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]] 。

image.png

看到一半一半有序,明显采用二分法,如下:

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];
    }
};

image.png

和昨天的二分查找类似

3. 第一个只出现一次的字符

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

image.png

经典空间换时间


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 ' ';
    }
};

image.png

总结

算是前面的复习