日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

AcWing之找出不改变数组找到重复的数字

發(fā)布時(shí)間:2024/7/5 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AcWing之找出不改变数组找到重复的数字 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目

給定一個(gè)長(zhǎng)度為 n+1 的數(shù)組nums,數(shù)組中所有的數(shù)均在 1~n 的范圍內(nèi),其中 n≥1。請(qǐng)找出數(shù)組中任意一個(gè)重復(fù)的數(shù),但不能修改輸入的數(shù)組。

樣例

給定 nums = [2, 3, 5, 4, 3, 2, 6, 7]。 返回 2 或 3。

思考題:

如果只能使用 O(1) 的額外空間,該怎么做呢?

方法一(使用了O(n)的空間):

class Solution { public:int duplicateInArray(vector<int>& nums) {int n = nums.size(); int nums2[n]={}; //用此數(shù)組類存儲(chǔ)重復(fù)的數(shù)字。 n個(gè)數(shù),哪個(gè)重復(fù) nums2[n]++ for(auto x: nums) {nums2[x]++;if(nums2[x] >= 2) {return x;}}} };

方法二(時(shí)間復(fù)雜度O(n),空間復(fù)雜度O(1))

class Solution { public:int duplicateInArray(vector<int>& nums) {int l = 1, r = nums.size()-1;int mid = (l + r)/2; // 劃分的區(qū)間:[l, mid], [mid + 1, r]int s = 0;while(l<r) {for(auto x:nums) { //查看nums數(shù)組中每個(gè)數(shù)值大小在其中一個(gè)區(qū)間的個(gè)數(shù)。 如在[1, mid]中的數(shù)字有多少if (x>=l && x<=mid)s+=1;if(s>mid-l+1) r=mid;else l=mid+1;}return r; } };

心得

方法一: 利用nums2數(shù)組記錄每個(gè)數(shù)的個(gè)數(shù)。 ++

方法二: 抽屜原理,逐漸縮小區(qū)間,查看n+1個(gè)空間n個(gè)數(shù)字,哪一側(cè)多一個(gè)數(shù)字。

(分治,抽屜原理) O(nlogn)O(nlogn)
這道題目主要應(yīng)用了抽屜原理和分治的思想。

抽屜原理:n+1 個(gè)蘋(píng)果放在 n 個(gè)抽屜里,那么至少有一個(gè)抽屜中會(huì)放兩個(gè)蘋(píng)果。 用在這個(gè)題目中就是,一共有 n+1 個(gè)數(shù),每個(gè)數(shù)的取值范圍是1到n,所以至少會(huì)有一個(gè)數(shù)出現(xiàn)兩次。

然后我們采用分治的思想,將每個(gè)數(shù)的取值的區(qū)間[1, n]劃分成[1, n/2]和[n/2+1, n]兩個(gè)子區(qū)間,然后分別統(tǒng)計(jì)兩個(gè)區(qū)間中數(shù)的個(gè)數(shù)。
注意這里的區(qū)間是指 數(shù)的取值范圍,而不是 數(shù)組下標(biāo)。

劃分之后,左右兩個(gè)區(qū)間里一定至少存在一個(gè)區(qū)間,區(qū)間中數(shù)的個(gè)數(shù)大于區(qū)間長(zhǎng)度。
這個(gè)可以用反證法來(lái)說(shuō)明:如果兩個(gè)區(qū)間中數(shù)的個(gè)數(shù)都小于等于區(qū)間長(zhǎng)度,那么整個(gè)區(qū)間中數(shù)的個(gè)數(shù)就小于等于n,和有n+1個(gè)數(shù)矛盾。

因此我們可以把問(wèn)題劃歸到左右兩個(gè)子區(qū)間中的一個(gè),而且由于區(qū)間中數(shù)的個(gè)數(shù)大于區(qū)間長(zhǎng)度,根據(jù)抽屜原理,在這個(gè)子區(qū)間中一定存在某個(gè)數(shù)出現(xiàn)了兩次。

依次類推,每次我們可以把區(qū)間長(zhǎng)度縮小一半,直到區(qū)間長(zhǎng)度為1時(shí),我們就找到了答案。

復(fù)雜度分析
時(shí)間復(fù)雜度:每次會(huì)將區(qū)間長(zhǎng)度縮小一半,一共會(huì)縮小 O(logn)O(logn) 次。每次統(tǒng)計(jì)兩個(gè)子區(qū)間中的數(shù)時(shí)需要遍歷整個(gè)數(shù)組,時(shí)間復(fù)雜度是 O(n)O(n)。所以總時(shí)間復(fù)雜度是 O(nlogn)O(nlogn)。
空間復(fù)雜度:代碼中沒(méi)有用到額外的數(shù)組,所以額外的空間復(fù)雜度是 O(1)O(1)。

作者:yxc
鏈接:https://www.acwing.com/solution/AcWing/content/693/
來(lái)源:AcWing
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

總結(jié)

以上是生活随笔為你收集整理的AcWing之找出不改变数组找到重复的数字的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。