国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[Go版]算法通關(guān)村第十五關(guān)青銅——用4KB內(nèi)存尋找重復元素

這篇具有很好參考價值的文章主要介紹了[Go版]算法通關(guān)村第十五關(guān)青銅——用4KB內(nèi)存尋找重復元素。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

海量數(shù)據(jù)中,此時普通的數(shù)組、鏈表、Hash、樹等等結(jié)構(gòu)有無效了 ,因為內(nèi)存空間放不下了。而常規(guī)的遞歸、排序,回溯、貪心和動態(tài)規(guī)劃等思想也無效了,因為執(zhí)行都會超時,必須另外想辦法。這類問題該如何下手呢?這里介紹三種非常典型的思路:

  1. 使用位存儲,使用位存儲最大的好處是占用的空間是簡單存整數(shù)的1/8。例如一個40億的整數(shù)數(shù)組,如果用整數(shù)存儲需要16GB左右的空間,而如果使用位存儲,就可以用2GB的空間,這樣很多問題就能夠解決了。

  2. 如果文件實在太大 ,無法在內(nèi)存中放下,則需要考慮將大文件分成若干小塊,先處理每個塊,最后再逐步得到想要的結(jié)果,這種方式也叫做外部排序。這樣需要遍歷全部序列至少兩次,是典型的用時間換空間的方法

  3. ,如果在超大數(shù)據(jù)中找第K大、第K小,K個最大、K個最小,則特別適合使用堆來做。而且將超大數(shù)據(jù)換成流數(shù)據(jù)也可以,而且?guī)缀跏俏ㄒ坏姆绞?,口訣就是“查小用大堆,查大用小堆”。
    常識補充:10億 ≈ 1G、100萬 ≈ 1M

題目:用4KB內(nèi)存尋找重復元素

給定一個數(shù)組,包含從1到N的整數(shù),N最大為32000,數(shù)組可能還有重復值,且N的取值不定,若只有4KB的內(nèi)存可用,該如何打印數(shù)組中所有重復元素。

思路分析:使用位存儲

如何存儲這32000個整數(shù)?

常規(guī)思路分析:32000個整數(shù),整數(shù)用int表示,一個int占用4個字節(jié)(byte),32000個整數(shù)所需內(nèi)存就是 :

32000 * 4 = 128000(byte)
32000 * 4 / 1024 = 125(KB)
125(KB) > 4(KB)	//可見,已經(jīng)超過題目要求的4KB內(nèi)存要求。

下面我們使用位存儲的方式:1個字節(jié)(byte)=8位(bit),32000個正數(shù)用32000個位就是:

32000 / 8 = 4000(byte)
32000 / 8 / 1024 = 3.9(KB)
3.9(KB)< 4(KB)	//如此,就滿足題意,使用了4KB就能存儲32000個元素

每個整數(shù)對應在位圖中的存儲狀態(tài)舉例

原數(shù)據(jù):				1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18  ...
該值在位圖中的索引值:	0  0  0  0  0  0  0  1  1  1  1  1  1  1  1  2  2  2  ... 
該值在位圖中的偏移量:	1  2  3  4  5  6  7  0  1  2  3  4  5  6  7  0  1  2  ...

1 對應的位圖值,和二進制值為:byteMap[0]	00000010
2 對應的位圖值,和二進制值為:byteMap[0]	00000100
3 對應的位圖值,和二進制值為:byteMap[0]	00001000
4 對應的位圖值,和二進制值為:byteMap[0]	00010000
5 對應的位圖值,和二進制值為:byteMap[0]	00100000
6 對應的位圖值,和二進制值為:byteMap[0]	01000000
7 對應的位圖值,和二進制值為:byteMap[0]	10000000
8 對應的位圖值,和二進制值為:byteMap[1]	00000001
9 對應的位圖值,和二進制值為:byteMap[1]	00000010
...

如何判斷是重復的?

既然我們用一個位(bit)代表一個數(shù)值,那么該位的兩種狀態(tài)0或1,就可以用于判斷該值是否存在。
例如:字節(jié)00001101表示以下情況:

  • 第 0 位(最低位)為 1,表示數(shù)字 1 出現(xiàn)過。
  • 第 1 位為 0,表示數(shù)字 2 沒有出現(xiàn)過。
  • 第 2 位為 1,表示數(shù)字 3 出現(xiàn)過。
  • 第 3 位為 1,表示數(shù)字 4 出現(xiàn)過。
  • 后續(xù)位為 0,表示數(shù)字 5 到 8 都沒有出現(xiàn)過。
mark := 1 << offset	//offset 就是偏移量
if (bitmap[index] & mask) != 0 {
    // 位已經(jīng)被設(shè)置,說明數(shù)字出現(xiàn)過
}
bitmap[index] |= mask	//設(shè)置該位值為1

具體的步驟

位圖(Bitmap)是一種數(shù)據(jù)結(jié)構(gòu),用于表示一組元素的狀態(tài)或?qū)傩裕ǔS枚M制位來表示,每個位代表一種狀態(tài)或?qū)傩?。在計算機科學中,位圖被廣泛用于各種應用,如圖像處理、數(shù)據(jù)壓縮、數(shù)據(jù)庫索引等。

  1. 初始化位圖:由于N最大是32000,可以是哦用一個長度為32000/8=4000的位圖,每個位可以表示一個整數(shù)。
  2. 遍歷數(shù)組,對于數(shù)組中的每個元素:
    • 計算x在位圖中的索引和位偏移。例如:x=5,則索引為5/8=0,位偏移為5%8=5。
    • 檢查位圖的索引位置是否已經(jīng)被標記。
      • 如果未被標記,則將其標記為已訪問;
      • 如果已經(jīng)被標記,則說明x是重復的,打印x。
  3. 打印重復元素。

復雜度:時間復雜度 O ( n ) O(n) O(n)、空間復雜度 O ( 1 ) O(1) O(1)

Go代碼

源碼地址: GitHub-golang版本(含單元測試代碼)

func FindDuplicatesIn32000(arr []int) (duplicate []int) {
	N := 32000
	bitmap := make([]byte, N/8+1)
	for _, num := range arr {
		// 計算 num 在 bitmap 中的索引
		// index := num / 8
		index := num >> 3
		// 計算 num 在 bitmap 中的偏移量
		offset := num % 8
		mark := byte(1 << offset)
		if bitmap[index]&mark != 0 {
			duplicate = append(duplicate, num)
		} else {
			bitmap[index] |= mark
		}
	}
	return
}

或者文章來源地址http://www.zghlxwxcb.cn/news/detail-676828.html

func FindDuplicatesIn32000(arr []int) (duplicate []int) {
	N := 32000
	// 或者這里不用+1,只要索引是base0的即可
	bitmap := make([]int, N/32)
	for _, num := range arr {
		num0 := num - 1 //base0開始
		index := num0 / 32
		offset := num0 % 32
		mark := 1 << offset
		if bitmap[index]&mark != 0 {
			duplicate = append(duplicate, num)
		} else {
			bitmap[index] |= mark
		}
	}
	return
}

到了這里,關(guān)于[Go版]算法通關(guān)村第十五關(guān)青銅——用4KB內(nèi)存尋找重復元素的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • 算法通關(guān)村第十五關(guān)——從40億個數(shù)中產(chǎn)生一個不存在的數(shù)的處理方法

    題目要求 :給定一個輸入文件,包含40億個非負整數(shù),請設(shè)計一個算法,產(chǎn)生一個不存在該文件中的整數(shù),假設(shè)你有1GB的內(nèi)存來完成這項任務。**** 解題中心思想 :存儲的不是這40億個數(shù)據(jù)本身,而是其對應的位置。 本題不用寫代碼,能把方法過程說清楚就可以。 方法 :

    2024年02月09日
    瀏覽(22)
  • 算法通關(guān)村第十七關(guān):青銅挑戰(zhàn)-貪心其實很簡單

    算法通關(guān)村第十七關(guān):青銅挑戰(zhàn)-貪心其實很簡單

    1. 難以解釋的貪心算法 貪心學習法則:直接做題,不考慮貪不貪心 貪心(貪婪)算法 是指在問題盡心求解時,在每一步選擇中都采取最好或者最優(yōu)(最有利)的選擇,從而希望能夠?qū)е陆Y(jié)果最好或者最優(yōu)的算法 貪心算法所得到的結(jié)果不一定是最優(yōu)的結(jié)果,但是都是相對近似最

    2024年02月09日
    瀏覽(28)
  • 算法通關(guān)村第十八關(guān):青銅挑戰(zhàn)-回溯是怎么回事

    算法通關(guān)村第十八關(guān):青銅挑戰(zhàn)-回溯是怎么回事

    回溯,最重要的算法之一 主要解決一些暴力枚舉也搞不定的問題,例如組合、分割、子集、排列、棋盤等 從性能角度來看回溯算法的效率并不高,但對于這些暴力都搞不定的算法能出結(jié)果就很好了,效率低點沒關(guān)系 回溯可視為遞歸的拓展,很多思想和解法都與遞歸密切相關(guān)

    2024年02月09日
    瀏覽(22)
  • 算法通關(guān)村第十六關(guān):青銅挑戰(zhàn)-滑動窗口其實很簡單

    算法通關(guān)村第十六關(guān):青銅挑戰(zhàn)-滑動窗口其實很簡單

    1. 滑動窗口基本思想 數(shù)組引入雙指針的背景: 很多算法會大量移動數(shù)組中的元素,頻繁移動元素會導致執(zhí)行效率低下或者超時,使用兩個變量能比較好的解決很多相關(guān)問題 數(shù)組雙指針,之前介紹過 對撞型 和 快慢型 兩種,滑動窗口思想就是快慢型的特例 滑動窗口 示例:

    2024年02月09日
    瀏覽(27)
  • [Go版]算法通關(guān)村第一關(guān)青銅——鏈表青銅挑戰(zhàn)筆記

    [Go版]算法通關(guān)村第一關(guān)青銅——鏈表青銅挑戰(zhàn)筆記

    單向鏈表圖示: 雙向鏈表圖示: 環(huán)形單向鏈表圖示: 環(huán)形雙向鏈表圖示: 源碼地址: GitHub-golang版本 如果是單向的,需要將當前節(jié)點 定位到要插入節(jié)點的前一個節(jié)點 ,否則一旦過了將無法回頭找到前一個節(jié)點 如果是雙向的,將當前節(jié)點 定位到要插入節(jié)點的前一個節(jié)點、

    2024年02月13日
    瀏覽(21)
  • [Go版]算法通關(guān)村第一關(guān)——鏈表青銅挑戰(zhàn)筆記

    [Go版]算法通關(guān)村第一關(guān)——鏈表青銅挑戰(zhàn)筆記

    單向鏈表圖示: 雙向鏈表圖示: 環(huán)形單向鏈表圖示: 環(huán)形雙向鏈表圖示: 源碼地址: GitHub-golang版本 如果是單向的,需要將當前節(jié)點 定位到要插入節(jié)點的前一個節(jié)點 ,否則一旦過了將無法回頭找到前一個節(jié)點 如果是雙向的,將當前節(jié)點 定位到要插入節(jié)點的前一個節(jié)點、

    2024年02月15日
    瀏覽(21)
  • [Go版]算法通關(guān)村第二關(guān)青銅——終于學會鏈表反轉(zhuǎn)了

    [Go版]算法通關(guān)村第二關(guān)青銅——終于學會鏈表反轉(zhuǎn)了

    題目鏈接:LeetCode-206. 反轉(zhuǎn)鏈表 源碼地址:GitHub-golang版本 說明:遍歷該鏈表,依次取出當前節(jié)點插入到新鏈表的首位(虛擬頭結(jié)點緊后)即可, 注意要提前保存當前節(jié)點的Next數(shù)據(jù) ,否則插入到新鏈表后就沒法繼續(xù)向下遍歷了。 說明:原理和方法1一致,只不過現(xiàn)在沒有虛擬

    2024年02月13日
    瀏覽(19)
  • [Go版]算法通關(guān)村第三關(guān)青銅——不簡單的數(shù)組增刪改查

    [Go版]算法通關(guān)村第三關(guān)青銅——不簡單的數(shù)組增刪改查

    在golang中,切片的底層就是數(shù)組,切片是對底層數(shù)組的引用,當傳遞一個切片給函數(shù)時,實際上是傳遞了切片的引用。因此,在函數(shù)內(nèi)部修改切片的內(nèi)容會影響原始切片。 先聲明并初始化一個長度為當前切片長度+1的切片 首部添加:將其余全部向后移動一位,然后給首位賦值

    2024年02月13日
    瀏覽(22)
  • [Go版]算法通關(guān)村第十二關(guān)黃金——字符串沖刺題

    [Go版]算法通關(guān)村第十二關(guān)黃金——字符串沖刺題

    題目鏈接:LeetCode-14. 最長公共前綴 以第一個子字符串為標準,遍歷其每個字符時,內(nèi)嵌遍歷其余子字符串的對應字符是否一致。不一致時,則返回當前字符之前的子字符串。 復雜度:時間復雜度 O ( n ? m ) O(n*m) O ( n ? m ) 、空間復雜度 O ( 1 ) O(1) O ( 1 ) 時間復雜度:其中 n

    2024年02月12日
    瀏覽(22)
  • 算法通關(guān)村|青銅挑戰(zhàn)----鏈表

    前言:數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ):創(chuàng)建+增刪改查 學習目標:單鏈表的創(chuàng)建+增刪改查,雙鏈表的創(chuàng)建+增刪改查 數(shù)據(jù)域+指針域 數(shù)據(jù)域:當前節(jié)點的元素值 指針域:當前節(jié)點保存的下一個節(jié)點的元素的地址,其中最后一個元素的指針域指向null 標準的面向?qū)ο蟮墓?jié)點的定義: LeetCode中節(jié)

    2024年02月15日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包