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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[算法] 举一反三之n重复数组中找唯一m重复异类数

發布時間:2025/3/16 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [算法] 举一反三之n重复数组中找唯一m重复异类数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

n重復數組,是指數組中的數字都出現n次;

唯一m重復異類數,是指存在唯一一個沒出現n次,只出現了m次的數;

這里我簡記它為nX+my問題,求解y,其中m < n,數組中都是整數;

?

3X+y問題

一直沒有精力刷leetcode,今天查問題無意中看到了leetcode 137:給定一個非空整數數組,除了某個元素只出現一次以外,其余每個元素均出現了三次;找出那個只出現了一次的元素。要求時間復雜度O(n),空間復雜度O(1);

沒有在第一時間想到思路,于是花時間研究了一下;

這是一個3X+y的問題;先給出最優解:

a, b = 0, 0for num in nums:a = (a ^ num) & ~bb = (b ^ num) & ~areturn a

?

在2X+y問題中,方法是使用異或操作一遍全數組,最終結果就是那個異類數,但從未深入想過為什么異或會對2X+y問題有效,因而也就無法想通為什么直接異或會對3X+y問題無效;

再看一遍異或的特點:

0 ^ 0 = 0 1 ^ 0 = 1 0 ^ 1 = 1 1 ^ 1 = 0

仔細看看,這是因為異或可以讓一個信息位(前面的那個1bit數),在接收到有效信息量(后面的那個1bit數,值為1時為有效)的時候,產生二態變化;

因而如果要解決3X+y問題,就需要有一個可以產生三態變化的操作符,單純的異或是肯定不行的,因為要對一個信息位保存三種狀態,至少需要兩個信息位,因而在原本的數字變量空間上操作是不夠的;

假定這個三態異或操作用符號^3表示;然后用兩個信息位(b, a)保存狀態,于是三態異或在接收到有效信息量(1)時的運算特點如下(接收到無效信息量0時不產生變化):

(0, 0) ^3 1 = (0, 1) (0, 1) ^3 1 = (1, 0) (1, 0) ^3 1 = (0, 0)

這個三態變化過程,其實是正常的兩位二進制數進位加法的一個修改,修改處在于,對于二進制10,再加1時,直接跳過11回到00;

因而這個狀態變化過程可描述為:

  • 兩位二進制數的低位a,在高位b為0時,進行二態變化;在高位b為1時,歸0;
  • 兩位二進制數的高位b,在低位a歸0時,進行二態變化;在低位a變為1時,保持為0;
  • 可見a與b的變化規律相似,都要求對方為0時自己進行二態變化,對方為1時自己為0,于是上面的最優解的計算過程就很容易寫出來了:

    a = (a ^ num) & ~bb = (b ^ num) & ~a

    3X+2y問題

    等等,為什么是return a,而不是return b呢?

    首先,上面這段代碼里的a、b各是一個數字,它位的每個二進制位組合起來,保存了對整個數組^3操作過程中每個二進制位的狀態變化;

    因為這個^3操作過程中,低位a在第一狀態有效,因而要求3X+y問題,需要return a;

    因而,如果題目改為:給定一個非空整數數組,除了某個元素只出現兩次以外,其余每個元素均出現了三次;找出那個只出現了兩次的元素。

    求解這個3X+2y問題,答案也就出來了,計算過程同上,而因為高位b在第二狀態有效,因而return b即可;

    4X+2y問題

    再發散思維,改題目:給定一個非空整數數組,除了某個元素只出現兩次以外,其余每個元素均出現了四次;找出那個只出現了兩次的元素。

    沿著上面的思路,需要做一個四態異或操作符^4,同樣需要兩個信息位進行狀態存儲,它對于有效信息(1)的運算特點如下:

    (0, 0) ^4 1 = (0, 1) (0, 1) ^4 1 = (1, 0) (1, 0) ^4 1 = (1, 1) (1, 1) ^4 1 = (0, 0)

    這就是標準的兩位二進制數加法,狀態變化過程可描述為:

  • 兩位二進制數的低位a,正常進行二態變化;
  • 兩位二進制數的高位b,在低位a進位的時候進位二態變化;
  • 于是計算過程可寫為:

    old_a = aa = (a ^ num)b = b ^ ((old_a ^ a) & ~a)

    其中(old_a ^ a) & ~a,意義為a由1變為0;

    由于這個b的計算核心算子是異或,異或與否合用有危險,不把(old_a ^ a)引進來會出現bug;

    因為要求的y出現2次,所以需要找第二狀態時的有效位,return b;

    4X+3y問題

    狀態數同時為4,計算過程同4X+2y,返回時找第三狀態時的有效位,因而也return b;

    5X+4y問題

    題目修改為:給定一個非空整數數組,除了某個元素只出現4次以外,其余每個元素均出現了5次;找出那個只出現了4次的元素。

    狀態數上升到5,需要做一個五態異或操作符^5,需要3個信息位(c, b, a)做狀態存儲,對有效信息(1)的運算特點如下:

    (0, 0, 0) ^5 1 = (0, 0, 1) (0, 0, 1) ^5 1 = (0, 1, 0) (0, 1, 0) ^5 1 = (0, 1, 1) (0, 1, 1) ^5 1 = (1, 0, 0) (1, 0, 0) ^5 1 = (0, 0, 0)

    狀態變化過程可描述為:

  • 三位二進制數的低位a,在高位c為0時,進行二態變化;在高位c為1時,歸0;
  • 三位二進制數的中位b,在高位c為0時,低位a進位的時候進位二態變化;在高位c為1時,歸0;
  • 三位二進制數的高位c,在低位a和中位b同時歸0時,進行二態變化;
  • 計算過程可寫為:

    old_a = aa = (a ^ num) & ~cb = (b ^ ((old_a ^ a) & ~a)) & ~cc = (c ^ num) & ~b & ~a

    由于y出現的次數是4,高位c在狀態4時有效,因而返回c;

    -----------------------------

    測試代碼:

    def X3_y1(nums):a, b = 0, 0for num in nums:a = (a ^ num) & ~bb = (b ^ num) & ~areturn adef X3_y2(nums):a, b = 0, 0for num in nums:a = (a ^ num) & ~bb = (b ^ num) & ~areturn bdef X4_y2(nums):a, b = 0, 0for num in nums:old_a = a a = (a ^ num)b = b ^ ((old_a ^ a) & ~a) return bdef X4_y3(nums):return X4_y2(nums)def X5_y4(nums):a, b, c = 0, 0, 0for num in nums:old_a = a a = (a ^ num) & ~cb = (b ^ ((old_a ^ a) & ~a)) & ~cc = (c ^ num) & ~b & ~areturn cprint (X3_y1([2, 3, 2, 2])) # 3 print (X3_y2([2, 3, 2, 3, 2])) # 3print (X4_y2([2, 2, 3, 2, 3, 2])) # 3 print (X4_y3([2, 2, 3, 2, 3, 3, 4, 3, 4, 4, 2])) #4 print (X4_y3([5, 5, 8, 5, 8, 8, 5])) # 8print (X5_y4([5, 5, 8, 5, 8, 8, 5, 8, 5])) # 8

    ?

    執行結果:

    3 3 3 4 8 8

    ?

    轉載于:https://www.cnblogs.com/ZisZ/p/10442182.html

    總結

    以上是生活随笔為你收集整理的[算法] 举一反三之n重复数组中找唯一m重复异类数的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。