剑指 Offer第 5 天 查找算法(剑指 Offer 04、剑指 Offer 11、剑指 Offer 50)

剑指 Offer 04. 二维数组中的查找

题目描述

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

示例

现有矩阵 matrix 如下:

[
  [1,   4,  7, 11, 15],
  [2,   5,  8, 12, 19],
  [3,   6,  9, 16, 22],
  [10, 13, 14, 17, 24],
  [18, 21, 23, 26, 30]
]

给定 target = 5,返回 true。
给定 target = 20,返回 false。

限制

0 <= n <= 1000
0 <= m <= 1000

思路

方法一:暴力。如果不考虑二维数组排好序的特点,则直接遍历整个二维数组的每一个元素,判断目标值是否在二维数组中存在。
方法二:线性查找。目标值从右上角开始,如果当前元素大于目标值,说明当前元素的下边的所有元素都一定大于目标值,因此往下查找不可能找到目标值,往左查找可能找到目标值。如果当前元素小于目标值,说明当前元素的左边的所有元素都一定小于目标值,因此往左查找不可能找到目标值,往下查找可能找到目标值。

代码

c++代码

class Solution {
    
    
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
    
    
        if(matrix.size()==0){
    
    
            return false;
        }
        int rows = matrix.size(),columns = matrix[0].size();
        int row = 0,column = columns - 1;
        //printf("%d %d\n",rows,columns);
        while(row<rows&&column>=0){
    
    
            int t = matrix[row][column];
            if(t==target){
    
    
                return true;
            }else if(t<target){
    
    
                row++;
            }else{
    
    
                column--;
            }
           // printf("%d %d\n",row,column);
        }
        return false;
    }
};

python代码

class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
        n = len(matrix)
        if n :
            m = len(matrix[0])
        for i in range(n):
            for j in range(m):
                if matrix[i][j] == target :
                    return True
        return False

剑指 Offer 11. 旋转数组的最小数字

题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。

给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为1。

示例 1

输入:[3,4,5,1,2]
输出:1

示例 2

输入:[2,2,2,0,1]
输出:0

思路

方法一:暴力
方法二:使用二分。只是l,r的值更新规则需要改改

代码

c++代码

class Solution {
    
    
public:
    int minArray(vector<int>& numbers) {
    
    
            int n = numbers.size();
            int m = 0;
            for(int i=0;i<n;i++){
    
    
                if(!i){
    
    
                    m = numbers[i];
                }else{
    
    
                    if(m>numbers[i]){
    
    
                        m = numbers[i];
                    }
                }
            }
            return m;
    }
};

python代码

class Solution:
    def minArray(self, numbers: List[int]) -> int:
        n = len(numbers)
        l = 0
        r = n-1
        while l<=r :
            mid = (l+r)>>1
            if numbers[mid]>numbers[r] :
                l = mid + 1
            elif numbers[mid]==numbers[r] :
                r-=1
            else:
                r = mid 
        return numbers[l]

剑指 Offer 50. 第一个只出现一次的字符

题目描述

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

示例 1

输入:s = “abaccdeff”
输出:‘b’

示例 2

输入:s = “”
输出:’ ’

限制

0 <= s 的长度 <= 50000

思路与算法

我们可以对字符串进行两次遍历。

在第一次遍历时,我们使用哈希映射统计出字符串中每个字符出现的次数。在第二次遍历时,我们只要遍历到了一个只出现一次的字符,那么就返回该字符,否则在遍历结束后返回空格。

代码

c++代码

class Solution {
    
    
public:
    char firstUniqChar(string s) {
    
    
        int n = s.length();
        int vis[50010]={
    
    0};
        for(int i=0;i<n;i++){
    
    
            vis[s[i]]++;
        }
        for(int i=0;i<n;i++){
    
    
            if(vis[s[i]]==1){
    
    
                return s[i];
            }
        }
        return ' ';
    }
};

python代码

class Solution:
    def firstUniqChar(self, s: str) -> str:
        f = collections.Counter(s)
        for i, ch in enumerate(s):
            if f[ch] == 1:
                return ch
        return ' '

这篇文章如果对小伙伴们有帮助的话,希望点个赞支持一下~ 十分感谢~

在这里插入图片描述


猜你喜欢

转载自blog.csdn.net/weixin_46627433/article/details/122928531