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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

每天一道LeetCode-----给定大小为n+1的数组,元素大小在[1 : n]之间,只有一个元素会重复出现多次,找到重复的那个

發(fā)布時(shí)間:2024/4/19 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 每天一道LeetCode-----给定大小为n+1的数组,元素大小在[1 : n]之间,只有一个元素会重复出现多次,找到重复的那个 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Find the Duplicate Number

原題鏈接Find the Duplicate Number

給定一定大小為n+1的數(shù)組,數(shù)組中的元素只可能是1到n中的數(shù)字,包括1和n。在數(shù)組中,有一個(gè)數(shù)字重復(fù)了多次,找到這個(gè)數(shù)字。
要求不能改變源數(shù)組的值,空間復(fù)雜度為O(1),時(shí)間復(fù)雜度要小于O(n2)。

注意數(shù)組中每個(gè)元素都只能是1到n之間的數(shù)字,這提供了一個(gè)有用的信息,即

  • 對于每個(gè)元素,可以用它的大小和[1: n]之間的數(shù)字比較

什么意思呢,假設(shè)數(shù)組中只有n個(gè)元素,而每個(gè)元素的大小都在[1 : n]之間,且沒有重復(fù)元素。那么對于1到n中的某個(gè)值w而言,整個(gè)數(shù)組中小于等于w的元素個(gè)數(shù)恰好等于w。可以通過先將數(shù)組排序后證明

接著,n個(gè)元素的時(shí)候恰好[1 : n]各一個(gè),現(xiàn)在,隨機(jī)從[1 : n]中選擇一個(gè)數(shù)字添加到數(shù)組中,使數(shù)組元素個(gè)數(shù)變?yōu)閚+1。此時(shí),對于某個(gè)值w而言。如果添加的數(shù)字小于等于w,那么小于等于w的元素個(gè)數(shù)將大于w(因?yàn)樘砑忧笆堑扔趙)。反之,如果添加的數(shù)字大于w,那么小于等于w的元素個(gè)數(shù)將小于w。

現(xiàn)在,假設(shè)數(shù)組元素個(gè)數(shù)為n+1,因?yàn)閿?shù)組元素只有n中取值,所以數(shù)組中會(huì)有重復(fù)元素,可能重復(fù)多次。那么此時(shí)對于1到n+1中的某個(gè)值w而言,整個(gè)數(shù)組中小于等于w的元素個(gè)數(shù)就會(huì)有三種可能

  • 數(shù)組中小于等于w的元素個(gè)數(shù)恰好等于w。這可以說明在數(shù)組所有元素中,值在[1 : w]這個(gè)范圍內(nèi)的元素沒有重復(fù),重復(fù)元素在[w + 1 : n]中。

    • 證明,反證法。如果有重復(fù)元素,那么[w + 1 : n]這個(gè)范圍內(nèi)的元素將不會(huì)重復(fù),那么數(shù)組中元素總個(gè)數(shù)為w + (n - w - 1 + 1) = n。而實(shí)際上數(shù)組元素個(gè)數(shù)為n+1,矛盾。
  • 數(shù)組中小于等于w的元素個(gè)數(shù)小于w。這可以說明在數(shù)組所有元素中,值在[1 : w]這個(gè)范圍內(nèi)的元素沒有重復(fù),重復(fù)元素在[w + 1 : n]中。

    • 證明,反證法。因?yàn)樾∮诘扔趙的元素個(gè)數(shù)小于w,所以大于w的元素個(gè)數(shù)大于n + 1 - w。如果[w + 1 : n]沒有重復(fù)元素,那么大于w的元素個(gè)數(shù)最多為n - w,矛盾。
  • 數(shù)組中小于等于w的元素個(gè)數(shù)大于w。這可以說明在數(shù)組的所有元素中,重復(fù)元素在[1 : w]中

    • 證明,反證法。如果[1 : w]范圍內(nèi)沒有重復(fù)的元素,那么小于等于w的元素個(gè)數(shù)最多為w,不可能大于w,矛盾。

通過這種劃分,讓上述w取當(dāng)前區(qū)間的中值,就可以采用二分法找到重復(fù)的那個(gè)元素,代碼如下

class Solution { public:int findDuplicate(vector<int>& nums) {int left = 1;int right = nums.size();while(left < right){/* 取區(qū)間的中值作為w */int middle = left + (right - left) / 2;int count = 0;/* 計(jì)算數(shù)組中所有小于等于w的元素個(gè)數(shù) */for(auto n : nums){if(n <= middle)++count;}/* 如果個(gè)數(shù)小于等于w,說明重復(fù)元素在[w+1 : n]的范圍內(nèi) */if(count <= middle)left = middle + 1;elseright = middle;}return left;} };

其實(shí)仔細(xì)想一下,時(shí)間復(fù)雜度小于O(n2)的無非O(1),O(lgn),O(n),O(nlgn)幾種,又要求空間復(fù)雜度是O(1),那么O(n)之前的幾乎都沒戲了,所以只可能是O(nlgn)。又因?yàn)镺(lgn)通常和二分法聯(lián)系在一起,所以很明顯需要使用二分法。又因?yàn)閿?shù)組元素在[1 : n]之間,所以可以用數(shù)組大小和下標(biāo)作比較,即通過比較然后利用二分縮小范圍。

總結(jié)

以上是生活随笔為你收集整理的每天一道LeetCode-----给定大小为n+1的数组,元素大小在[1 : n]之间,只有一个元素会重复出现多次,找到重复的那个的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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