力扣--連結串列演算法
力扣--連結串列演算法
刪除中間點
內容
實現一種演算法,刪除單向連結串列中間的某個節點(即不是第一個或最後一個節點),假定你只能訪問該節點。
示例
輸入:單向連結串列a->b->c->d->e->f中的節點c
結果:不返回任何資料,但該連結串列變為a->b->d->e->f
程式碼
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public void deleteNode(ListNode node) {
node.val = node.next.val; //將下一節點的值賦給當前節點
node.next = node.next.next; //當前節點的下一個節點為下下節點,刪除當前節點
}
}
複雜度
時間複雜度:O(1)。
空間複雜度:O(1)。
二進位制連結串列轉整數
內容
給你一個單連結串列的引用結點 head。連結串列中每個結點的值不是 0 就是 1。已知此連結串列是一個整數數字的二進位制表示形式。請你返回該連結串列所表示數字的 十進位制值 。
示例
輸入:head = [1,0,1]
輸出:5
解釋:二進位制數 (101) 轉化為十進位制數 (5)
程式碼
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int getDecimalValue(ListNode head) {
ListNode cur = head;
int ans = 0;
while(cur != null){
//連結串列只有0/1
ans = ans * 2 + cur.val;
cur = cur.next;
}
return ans;
}
}
複雜度
時間複雜度:O(N),其中N是連結串列中的節點個數。
空間複雜度:O(1)。
返回倒數第K個節點
內容
實現一種演算法,找出單向連結串列中倒數第 k 個節點。返回該節點的值。
示例
輸入: 1->2->3->4->5 和 k = 2
輸出: 4
程式碼
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int kthToLast(ListNode head, int k) {
if(k <= 0 || head == null){
return 0;
}
ListNode fast = head;
ListNode slow = head;
//讓快指標先快走K-1步
while(k - 1 > 0){
fast = fast.next;
k--;
}
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next;
}
return slow.val;
}
}
複雜度
時間複雜度 O(N) :N為連結串列長度。
空間複雜度 O(1)。
從尾到頭列印連結串列
內容
輸入一個連結串列的頭節點,從尾到頭反過來返回每個節點的值(用陣列返回)。
示例
輸入:head = [1,3,2]
輸出:[2,3,1]
程式碼
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int[] reversePrint(ListNode head) {
//使用棧,先進後出原則
Stack<ListNode> stack = new Stack<ListNode>();
ListNode node = head;
while(node != null){
stack.push(node);
node = node.next;
}
int size = stack.size();
int[] print = new int[size];
for(int i = 0;i < size;i++){
print[i] = stack.pop().val;
}
return print;
}
}
複雜度
時間複雜度:O(n)正向遍歷一遍連結串列,然後從棧彈出全部節點,等於又反向遍歷一遍連結串列。
空間複雜度:O(n)額外使用一個棧儲存連結串列中的每個節點。
連結串列的中間結點
內容
給定一個頭結點為 head 的非空單連結串列,返回連結串列的中間結點。
如果有兩個中間結點,則返回第二個中間結點。
示例
輸入:[1,2,3,4,5]
輸出:此列表中的結點 3 (序列化形式:[3,4,5])
返回的結點值為 3 。 (測評系統對該結點序列化表述是 [3,4,5])。
注意,我們返回了一個 ListNode 型別的物件 ans,這樣:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode middleNode(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
}
複雜度
時間複雜度:O(N)O(N),其中 NN 是給定連結串列的結點數目。
空間複雜度:O(1)O(1),只需要常數空間存放 slow 和 fast 兩個指標。
移除重複節點
內容
編寫程式碼,移除未排序連結串列中的重複節點。保留最開始出現的節點。
示例
輸入:[1, 2, 3, 3, 2, 1]
輸出:[1, 2, 3]
程式碼
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeDuplicateNodes(ListNode head) {
if(head == null){
return head;
}
//HashSet特點無序不可重複
Set<Integer> occurred = new HashSet<Integer>();
//先將頭節點的值加進雜湊表中
occurred.add(head.val);
ListNode pos = head;
while(pos.next != null){
ListNode cur = pos.next;
if(occurred.add(cur.val)){
pos = pos.next;
}else{
pos.next = pos.next.next;
}
}
pos.next = null;
return head;
}
}
複雜度
時間複雜度:O(N),其中 N 是給定連結串列中節點的數目。
空間複雜度:O(N)。在最壞情況下,給定連結串列中每個節點都不相同,雜湊表中需要儲存所有的 N 個值。
反轉連結串列
內容
反轉一個單連結串列。
示例
輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL
程式碼
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while(curr != null){
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
}
複雜度
時間複雜度:O(n),假設 n 是列表的長度,時間複雜度是 O(n)。
空間複雜度:O(1)。
合併兩個有序連結串列
內容
將兩個升序連結串列合併為一個新的 升序 連結串列並返回。新連結串列是通過拼接給定的兩個連結串列的所有節點組成的。
示例
輸入:1->2->4, 1->3->4
輸出:1->1->2->3->4->4
程式碼
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode prehead = new ListNode(-1);
ListNode prev = prehead;
while(l1 != null && l2 != null){
if(l1.val <= l2.val){
prev.next = l1;
l1 = l1.next;
}else{
prev.next = l2;
l2 = l2.next;
}
prev = prev.next;
}
//合併後l1和l2最多隻有一個還未被合併完,我們直接將連結串列末尾指向未合併完的連結串列即可
prev.next = l1 == null ? l2 : l1;
return prehead.next;
}
}
複雜度
時間複雜度:O(n + m)O(n+m) ,其中 nn 和 mm 分別為兩個連結串列的長度。因為每次迴圈迭代中,l1 和 l2 只有一個元素會被放進合併連結串列中, 因此 while 迴圈的次數不會超過兩個連結串列的長度之和。所有其他操作的時間複雜度都是常數級別的,因此總的時間複雜度為 O(n+m)O(n+m)。
空間複雜度:O(1)O(1) 。我們只需要常數的空間存放若干變數。
連結串列相交
內容
給定兩個(單向)連結串列,判定它們是否相交併返回交點。請注意相交的定義基於節點的引用,而不是基於節點的值。換句話說,如果一個連結串列的第k個節點與另一個連結串列的第j個節點是同一節點(引用完全相同),則這兩個連結串列相交。
示例
輸入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
輸出:Reference of the node with value = 8
輸入解釋:相交節點的值為 8 (注意,如果兩個列表相交則不能為 0)。從各自的表頭開始算起,連結串列 A 為 [4,1,8,4,5],連結串列 B 為 [5,0,1,8,4,5]。在 A 中,相交節點前有 2 個節點;在 B 中,相交節點前有 3 個節點。
程式碼
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode t1 = headA;
ListNode t2 = headB;
while(t1 != t2){
t1 = t1 != null ? t1.next : headB;
t2 = t2 != null ? t2.next : headA;
}
return t2;
}
}
複雜度
內容
示例
程式碼
複雜度
內容
示例
程式碼
複雜度
內容
示例
程式碼
複雜度
內容
示例
程式碼
複雜度
內容
示例
程式碼
複雜度
內容
示例
程式碼
複雜度
內容
示例
程式碼
複雜度
內容
示例
程式碼
複雜度
內容
示例
程式碼
複雜度
內容
示例
程式碼
複雜度
內容
示例
程式碼
複雜度
內容
示例
程式碼
複雜度
內容
示例
程式碼
複雜度
內容
示例
程式碼
複雜度
相關文章
- [Golang]力扣LeetBook—初級演算法—連結串列—迴文連結串列(快慢指標)Golang力扣演算法指標
- Go資料結構與力扣—連結串列Go資料結構力扣
- 力扣-203. 移除連結串列元素力扣
- 力扣(LeetCode) -143 重排連結串列力扣LeetCode
- 力扣 leetcode 86. 分隔連結串列力扣LeetCode
- TODO-力扣-707. 設計連結串列力扣
- 力扣 147. 對連結串列進行插入排序力扣排序
- 力扣學習筆記:142. 環形連結串列 II力扣筆記
- 力扣-83. 刪除排序連結串列中的重複元素力扣排序
- 演算法-連結串列演算法
- 把玩演算法 | 連結串列演算法
- 結構與演算法(03):單向連結串列和雙向連結串列演算法
- 資料結構與演算法——連結串列 Linked List(單連結串列、雙向連結串列、單向環形連結串列-Josephu 問題)資料結構演算法
- 演算法面試(一) 連結串列演算法面試
- 初級演算法-連結串列演算法
- 筆記--連結串列演算法筆記演算法
- 演算法基礎~連結串列~排序連結串列的合併(k條)演算法排序
- 連結串列-雙向連結串列
- 連結串列-迴圈連結串列
- 連結串列面試題(二)---連結串列逆序(連結串列反轉)面試題
- 【小白學演算法】5.連結串列(linked list)、連結串列的新增演算法
- 演算法題中的連結串列演算法
- 演算法 - 連結串列操作思想 && case演算法
- 連結串列4: 迴圈連結串列
- 連結串列-單連結串列實現
- 資料結構與演算法-連結串列資料結構演算法
- 【資料結構與演算法學習】線性表(順序表、單連結串列、雙向連結串列、迴圈連結串列)資料結構演算法
- 連結串列入門與插入連結串列
- (連結串列)連結串列的排序問題排序
- 演算法題:反轉一個單連結串列&判斷連結串列是否有環演算法
- 連結串列
- 玩轉演算法面試之連結串列演算法面試
- 演算法:排序連結串列:歸併排序演算法排序
- 【演算法詳解】有環連結串列演算法
- Swift 演算法實戰之路:連結串列Swift演算法
- 資料結構與演算法分析——連結串列資料結構演算法
- JavaScript資料結構與演算法(連結串列)JavaScript資料結構演算法
- 【Algorithm】連結串列演算法中啞結點作用Go演算法