leetcode演算法題 劍指Offer篇(13)

2021-10-23 14:12:39 字數 3811 閱讀 6970

1.1 題目描述:

陣列中有乙個數字出現的次數超過陣列長度的一半,請找出這個數字。

1.2 題解

1.2.1 摩爾投票法

// 驗證 x 是否為眾數

for(

int num : nums)

if(num == i) count++

;return count > nums.length /

2? i :0;

// 當無眾數時返回 0

}2.1 題目描述:

輸入整數陣列 arr ,找出其中最小的 k 個數。例如,輸入4、5、1、6、2、7、3、8這8個數字,則最小的4個數字是1、2、3、4。

2.2 題解

2.2.1 計數排序

public

int[

]getleastnumbers

(int

arr,

int k)

// 統計每個數字出現的次數

int[

] counter =

newint

[10001];

for(

int num: arr)

// 根據counter陣列從頭找出k個數作為返回結果

int[

] res =

newint

[k];

int idx =0;

for(

int num =

0; num < counter.length; num++)if

(idx == k)

}return res;

}

2.2.2 二叉搜尋樹
public

int[

]getleastnumbers

(int

arr,

int k)

// treemap的key是數字, value是該數字的個數。

// cnt表示當前map總共存了多少個數字。

treemap

map =

newtreemap

<

>()

;int cnt =0;

for(

int num: arr)

// 2. 否則,取出map中最大的key(即最大的數字), 判斷當前數字與map中最大數字的大小關係:

// 若當前數字比map中最大的數字還大,就直接忽略;

// 若當前數字比map中最大的數字小,則將當前數字加入map中,並將map中的最大數字的個數-1。

map.entry

entry = map.

lastentry()

;if(entry.

getkey()

> num)

else}}

// 最後返回map中的元素

int[

] res =

newint

[k];

int idx =0;

for(map.entry

entry: map.

entryset()

)}return res;

}

2.2.3 大根堆(前 k 小) / 小根堆(前 k 大)
public

int[

]getleastnumbers

(int

arr,

int k)

// 預設是小根堆,實現大根堆需要重寫一下比較器。

queue

pq =

newpriorityqueue

<

>

((v1, v2)

-> v2 - v1)

;for

(int num: arr)

else

if(num < pq.

peek()

)}// 返回堆中的元素

int[

] res =

newint

[pq.

size()

];int idx =0;

for(

int num: pq)

return res;

}

2.2.4 用快排最最最高效解決
public

int[

]getleastnumbers

(int

arr,

int k)

// 最後乙個引數表示我們要找的是下標為k-1的數

return

quicksearch

(arr,

0, arr.length -

1, k -1)

;}private

int[

]quicksearch

(int

nums,

int lo,

int hi,

int k)

// 否則根據下標j與k的大小關係來決定繼續切分左段還是右段。

return j > k?

quicksearch

(nums, lo, j -

1, k)

:quicksearch

(nums, j +

1, hi, k);}

// 快排切分,返回下標j,使得比nums[j]小的數都在j的左邊,比nums[j]大的數都在j的右邊。

private

intpartition

(int

nums,

int lo,

int hi)

int t = nums[j]

; nums[j]

= nums[i]

; nums[i]

= t;

} nums[lo]

= nums[j]

; nums[j]

= v;

return j;

}

3.1 題目描述:
如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。

例如,[2,3,4] 的中位數是 3

[2,3] 的中位數是 (2 + 3) / 2 = 2.5

設計乙個支援以下兩種操作的資料結構:

void addnum(int num) - 從資料流中新增乙個整數到資料結構中。

double findmedian() - 返回目前所有元素的中位數。

3.2 題解

3.2.1 大小堆

leetcode演算法題 劍指Offer篇(1)

1.1 題目描述 在乙個長度為 n 的陣列 nums 裡的所有數字都在 0 n 1 的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意乙個重複的數字。1.2 題解 1.2.1 利用map結構public intfindrepeatnumber i...

leetcode演算法題 劍指Offer篇(17)

1.1 題目描述 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。1.2 題解 1.2.1 暴力求解 public intreversepairs int nums return count 1.2.2 歸併排序public...

leetcode演算法題 劍指Offer篇(20)

1.1 題目描述 輸入乙個遞增排序的陣列和乙個數字s,在陣列中查詢兩個數,使得它們的和正好是s。如果有多對數字的和等於s,則輸出任意一對即可。1.2 題解 1.2.1 雙指標public int twosum int nums,int target else if temp target i els...