剑指Offer刷题记录_Day5

本文探讨了剑指Offer中的两个查找算法问题:二维数组的查找及旋转数组的最小值。通过对不同解决策略的分析,如暴力法、二分搜索及哈希表的应用,为读者提供了高效解决问题的思路。

剑指Offer刷题记录_Day5

查找算法(中等)

Q1 二维数组的查找

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

  • 思路一:暴力法 时间复杂度O(nm)空间复杂度O(1)

  • 思路二:由于二维数组从左至右,从上至下的性质,我们考虑能否用二分搜索的方法。联想BST(Binary Search Tree),从根节点出发,小于当前结点向右搜索,大于当前结点向左搜索。观察题目所构造的矩阵,从左上开始查找和BST情况相似,因此只要想出查找失败的条件即可。注意数组为空的情况。

class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {             
        if (matrix.size() == 0 || matrix[0].size() == 0) 
        {
            return false;
        }
        int m = matrix[0].size(); //列
        int n = matrix.size();    //行
        int i = 0,j = m-1,temp;
        while(i < n && j>=0)
        {
            temp = matrix[i][j];
            if(temp == target) return true;
            else if(temp > target) j--;
            else i++;
        }
        return false;
   
    }
};

Q2 旋转数组的最小值

题目描述:

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

思路一:遍历,知道第一个小于前一个值的值or没有则选择第一个

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

    }
};

思路二:二分,寻找旋转点

class Solution {
public:
    int minArray(vector<int>& numbers) {
       int i=0,j=numbers.size()-1,mid;
       while(i<j)
       {
           mid = (i+j)/2;
           if(numbers[mid] == numbers[j]) j--;
           else if(numbers[mid] < numbers[j]) j = mid;
           else i = mid + 1 ;
       }
       return numbers[i];

    }
};

Q3 第一个只出现一次的字符

思路:主要考察对数据结构的理解,可以构造哈希表<元素值,true if 出现次数为1 else false>,然后再遍历一遍字符串数组输出第一个只出现一次的字符

class Solution {
public:
    char firstUniqChar(string s) {
        unordered_map <char, bool> hash;
        for(char c : s)
            hash[c] = (hash.find(c) == hash.end()); //若第一次出现,则返回true
                                                    //若存在,说明不止一个返回false 
        for(char c : s)
            if(hash[c]) return c;
        return ' ';
    }


};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值