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

剑指offer打卡第四天

  • 查找算法(简单)
    • 一、剑指 Offer 03. 数组中重复的数字
    • 二、剑指 Offer 53 - I. 在排序数组中查找数字 I
    • 三、剑指 Offer 53 - II. 0~n-1中缺失的数字


查找算法(简单)


一、剑指 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;
    }
};

你可能感兴趣的:(剑指offer,算法,leetcode)