剑指offer--查找算法(简单)

这篇博客详细介绍了三种查找算法的解决方案:使用unordered_set找数组中重复数字,通过二分查找法在排序数组中统计目标数字出现次数,以及利用数学公式寻找0~n-1中缺失的数字。代码实现涵盖C++,重点讲解了算法思路和步骤。
摘要由CSDN通过智能技术生成


查找算法(简单)


一、剑指 Offer 03. 数组中重复的数字

【题目描述】 找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
【分析】:C++11中对unordered_set描述大体如下:无序集合容器(unordered_set)是一个存储唯一(unique,即无重复)的关联容器(Associative container),容器中的元素无特别的秩序关系,该容器允许基于值的快速元素检索,同时也支持正向迭代。

函数模板

template < class Key,
    class Hash = hash<Key>,
    class Pred = equal_to<Key>,
    class Alloc = allocator<Key>
> class unordered_set;

【C++代码】
代码如下:

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        unordered_set<int> ss;
        for(int i = 0;i < nums.size();i++){
            if(ss.count(nums[i])!=0)
                return nums[i];
            ss.insert(nums[i]);
        }
        return 0;
    }
};

二、剑指 Offer 53 - I. 在排序数组中查找数字 I

【题目描述】 统计一个数字在排序数组中出现的次数。
【分析】 解题思路:
排序数组中的搜索问题,二分解法
排序数组nums中的所有数字target形成一个窗口,记窗口左/右边界索引分别为left和right分别对应窗口左边/右边的首个元素。
本题要求统计数字target出现的次数,可转换为:使用二分法分别找到左边界left和右边界right,易得数字target的数量为right-left-1;

【C++代码】

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if(nums.empty()) return 0;
        int l = 0,r = nums.size()-1;
        while(l < r){
            int mid = l + r >> 1;
            if(nums[mid] >= target)
                r = mid;
            else 
                l = mid + 1;
        }

        if(nums[r]!= target) return 0;
        int start = r;
        l = 0,r = nums.size()-1;
        while(l < r){
            int mid = (long long)l + (long long)r + 1>>1;
            if(nums[mid] <= target) 
                l = mid;
            else 
                r = mid - 1;
        }
        int end = r;
        return end - start + 1;
    }
};

算法解析:
1、初始化:左边界 i = 0,右边界 j = nums.size()-1;
2、循环二分:当闭区间[i,j]无元素时跳出

  1. 计算中点位置m = (i+ j)/2下取整
  2. 若nums[m] < target,则target在闭区间[m+1,j]中,因此执行i = m+1;
  3. 若nums[m] > target, 则target在闭区间[i,m-1]中,因此执行j = m-1;
  4. 若nums[m] = target, 则右边界right在闭区间[m+1,j]中,左边界left在闭区间[i,m-1]中

三、剑指 Offer 53 - II. 0~n-1中缺失的数字

【题目描述】 一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/que-shi-de-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

【分析】
前n项和的计算公式,求和公式的应用

【C++代码】
代码如下:

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n = nums.size();
        int res = (n)*(n+1)/2;
        for(auto x :nums) res -= x;
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值