鍊錶演算法操作5大經典集合

2021-10-08 18:40:57 字數 4242 閱讀 1625

定義乙個函式,輸入乙個鍊錶的頭節點,反轉該鍊錶並輸出反轉後鍊錶的頭節點。

示例:輸入: 1->2->3->4->5->null

輸出: 5->4->3->2->1->null

直接將鍊錶看成兩部分,一部分是已經反轉的,一部分是待反轉的。

可以如下:

分割開,每次需要使用三個指標,乙個是已經反轉的部分,乙個是待反轉部分,乙個是待反轉部分的下乙個。

**如下:

public listnode reverselist

(listnode head)

return pre;

}

遞迴解法

遍歷到鍊錶尾部,再將尾結點的下乙個指向前乙個結點即可。

這個不好畫圖,簡單說明如下:

先找到鍊錶尾。

由於一般會在head.next為空結束,說以當前節點會是head,那麼我們有了當前節點,以及當前節點後的結點,只需要設定next結點即可。

public listnode reverselist2

(listnode head)

listnode reshead =

reverselist2

(head.next)

; head.next.next = head;

head.next = null;

return reshead;

}

輸入兩個遞增排序的鍊錶,合併這兩個鍊錶並使新鍊錶中的節點仍然是遞增排序的。

示例1:

輸入:1->2->4, 1->3->4

輸出:1->1->2->3->4->4

用偽頭結點,將小元素鏈結到後面,最後返回偽頭結點的next即可。

public listnode mergetwolists

(listnode l1, listnode l2)

else

res = res.next;

} res.next = p1 != null?

p1:p2;

return reshead.next;

}

給定乙個帶有頭結點 head 的非空單鏈表,返回鍊錶的中間結點。

如果有兩個中間結點,則返回第二個中間結點。

示例 1:

輸入:[1,2,3,4,5]

輸出:此列表中的結點 3 (序列化形式:[3,4,5])

示例 2:

輸入:[1,2,3,4,5,6]

輸出:此列表中的結點 4 (序列化形式:[4,5,6])

由於該列表有兩個中間結點,值分別為 3 和 4,我們返回第二個結點。

快慢指標,快指標到達尾部,返回慢指標對應的值即可。

t:n。s:1;

public listnode middlenode

(listnode head)

listnode slow = head, fast = head.next;

while

(fast != null)

return slow;

}

用陣列儲存,直接用資料的中點索引即可。

t:n;s:n

if

(head == null || head.next == null)

listnode[

] listnodes =

newlistnode

[100];

int i =0;

listnode p = head;

while

(p != null)

return

(i &1)

==1? listnodes[i /2]

: listnodes[i /2-

1];

單指標。掃瞄一遍得到鍊錶長,再掃瞄一遍取中點。

t:n。s:1

public listnode middlenode3

(listnode head)

int i = len /2;

while

(i--

>=0)

return p2;

}

設計和構建乙個「最近最少使用」快取,該快取會刪除最近最少使用的專案。快取應該從鍵對映到值(允許你插入和檢索特定鍵對應的值),並在初始化時指定最大容量。當快取被填滿時,它應該刪除最近最少使用的專案。

它應該支援以下操作: 獲取資料 get 和 寫入資料 put 。

獲取資料 get(key) - 如果金鑰 (key) 存在於快取中,則獲取金鑰的值(總是正數),否則返回 -1。

寫入資料 put(key, value) - 如果金鑰不存在,則寫入其資料值。當快取容量達到上限時,它應該在寫入新資料之前刪除最近最少使用的資料值,從而為新的資料值留出空間。

使用hashmap + 雙向鍊錶結點實現,再使用兩個哨兵頭尾結點簡化程式設計。

public

class

lruhashmap

public

void

put(

int key,

int value)

banode n = map.

get(key)

;// 有值則修改,放到頭部

if(n != null)

else

}private

void

afterinsertion()

}public

intget

(int key)

banode n = map.

get(key);if

(n == null)

afteraccess

(n);

return n.value;

}/**

* 被訪問之後,將其前後結點連線起來,將被訪問結點移至頭部

*/private

void

afteraccess

(banode n)

private

void

movetohead

(banode n)

private

boolean

isempty()

private

void

init()

}

給定乙個鍊錶,判斷鍊錶中是否有環。

為了表示給定鍊錶中的環,我們使用整數 pos 來表示鍊錶尾連線到鍊錶中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該鍊錶中沒有環。

示例 1:

輸入:head = [3,2,0,-4], pos = 1

輸出:true

解釋:鍊錶中有乙個環,其尾部連線到第二個節點。

快慢指標,當快指標等於慢指標,表明有環

public

boolean

hascycle

(listnode head)

listnode slow = head, fast = head.next;

while

(slow != fast)

slow = slow.next;

fast = fast.next.next;

}return

true

;}

這個沒找到題目,我自己驗證了幾個示例,如果有問題還請指出。

也是快慢指標的思路,記錄第一次相遇時的計數器,再記錄第二次的,相減就是環長。(因為可能會很湊巧直接碰到,所以沒有辦法通過一次的碰面確定環長。)

public

static

intgetcirclelen

(node head)

node slow = head, fast = head.next;

int firstmeet =-1

;int count =0;

while

(firstmeet ==-1

|| slow != fast)

if(slow == fast)

count++

; slow = slow.next;

fast = fast.next.next;

}return count - firstmeet;

}

三大經典表連線

nested loop join 區域性掃瞄的oltp 驅動結果集的條數決定被驅動表的訪問次數 效能與驅動表順序有關 無特殊寫法限制 驅動表 被驅動表限制條件建立索引 小結果集驅動大結果集 hash join olap全表掃瞄 兩表只會訪問1次或0次 效能與驅動表順序有關 不能用於 between ...

五大經典演算法

據說有人歸納了計算機的五大常用演算法,它們是貪婪演算法,動態規劃演算法,分治演算法,回溯演算法以及分支限界演算法。雖然不知道為何要將這五個演算法歸為最常用的演算法,但是毫無疑問,這五個演算法是有很多應用場景的,最優化問題大多可以利用這些演算法解決。演算法的本質就是解決問題。當資料量比較小時,其實根本...

資料探勘18大經典演算法

本文所有涉及到的資料探勘 的都放在了我的github上了。大概花了將近2個月的時間,自己把18大資料探勘的經典演算法進行了學習並且進行了 實現,涉及到了決策分類,聚類,鏈結挖掘,關聯挖掘,模式挖掘等等方面。也算是對資料探勘領域的小小入門了吧。下面就做個小小的總結,後面都是我自己相應演算法的博文鏈結,...