您的位置:首页 > 财经 > 金融 > 供应商管理系统软件srm_微信小程序点餐系统怎么做_seo是什么意思如何实现_关键词研究工具

供应商管理系统软件srm_微信小程序点餐系统怎么做_seo是什么意思如何实现_关键词研究工具

2025/5/1 18:32:16 来源:https://blog.csdn.net/weixin_46366676/article/details/145075655  浏览:    关键词:供应商管理系统软件srm_微信小程序点餐系统怎么做_seo是什么意思如何实现_关键词研究工具
供应商管理系统软件srm_微信小程序点餐系统怎么做_seo是什么意思如何实现_关键词研究工具

如果一个题目限定了数据范围是[1, n]内的整数,那么这个题目可以思考的就是

nums[i]和 i 的关系,769. 最多能完成排序的块 这个题就使用到了子数组中最大值和 连续[0, n - 1]的关系

而对于本题来说,也可以思考[1, n] 和 nums[i] 的关系,想要观察他们之间的关系

以nums = [1,3,4,2,2]为例,可以画出如下散点图,下列散点图,因为这个题要求不能更改原数组,而且只能使用o(1)的空间复杂度设计算法,所以直接画出{1, 1}, {2, 3}, {3, 4}, {4, 2}, {5, 2} 这几个点

这个图 已经包含了所有nums中的信息,那么如何去解读这张图的信息来找到 2这个出现两次的纵坐标呢?

        一个很自然的想法就是画一条水平线,让这条水平线从上往平移,一旦平移到穿过两个即以上的点,那么此时这条水平线的纵坐标就是要找的重复两次的数,这样的想法就是两个for循环来实现的o(n2) 的算法,能够满足题目要求,但是这样的算法不能通过全部测试用例

那么怎么解决这个问题?首先想一想有没有o(nlogn)的解法?

logn的解法中二分就是很常见的算法,可是二分只能针对有序数组进行啊,1 3 4 2 2 算哪门子的有序数组?那不如换个思路,在上图中画出四条平行线,y1 = 1, y2 = 2, y3 = 3, y4 = 4,观察后发现,

y1 穿过以及其下方的点有1个,y2 穿过以及其下方的点有3个,

y3 穿过以及其下方的点有4个,y4 穿过以及其下方的点有5个

正好是在 y2 处多穿过了两个点,

此时可以根据以上事实发现如下规律:

要找的数是[1,n-1]中的某个target,这个target满足下列性质

假设x是属于[1,n-1]中的一个数,记在nums中小于等于x的有yx个

如果yx <= x,则x 一定不是要找到的target,且x < target

如果yx > x,则纳入target备选集合中,且x >= target

而target就是备选集合中最小的那个数

那么就可以使用如下算法

class Solution {
public:int findDuplicate(vector<int>& nums) {int n = nums.size();int l = 1, r = n - 1;while(l < r){int mid = l + (r - l) / 2;int count = 0;for(int i = 0; i < n; ++i){if(nums[i] <= mid){count++;}}if(count <= mid){l = mid + 1;}else{r = mid;}}return l;}
};

其实现原理可以通过几张图演示

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com