LeetBook 謹記錄個人的學習過程
阿新 • • 發佈:2020-12-02
LeetBook 演算法題 題集,謹記錄個人的學習過程
在本人學習的過程中 ,
遇到大量的 使用哨兵節點 俗稱偽頭 或者 偽尾。
,還有雙指標 ,
簡化新增刪除操作 ,
ListNode newNode = new ListNode(0,head);
1.設計連結串列 (單向連結串列)
public class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } class MyLinkedList { int size; ListNode head; public MyLinkedList() { size = 0; head = new ListNode(0); } public int get(int index) { if (index < 0 || index >= size) { return -1; } ListNode curr = head; for(int i = 0; i < index + 1; ++i) curr = curr.next; return curr.val; } public void addAtHead(int val) { addAtIndex(0, val); } public void addAtTail(int val) { addAtIndex(size, val); } public void addAtIndex(int index, int val) { if (index > size) { return; } if (index < 0) { return; } ++size; ListNode pred = head; for(int i = 0; i < index; ++i) { pred = pred.next; } ListNode toAdd = new ListNode(val); toAdd.next = pred.next; pred.next = toAdd; } public void deleteAtIndex(int index) { if (index < 0 || index >= size) { return; } size--; ListNode pred = head; for(int i = 0; i < index; ++i) { pred = pred.next; } pred.next = pred.next.next; } }
環形連結串列 (給定一個連結串列,判斷連結串列中是否有環。)
public class Solution { public boolean hasCycle(ListNode head) { if (head == null || head.next == null) { return false; } ListNode show = head; ListNode pNode = head.next; while (show != pNode) { if (pNode == null || pNode.next == null) { return false; } show = show.next; pNode = pNode.next.next; } return true; } }
環形連結串列 (給定一個連結串列,返回連結串列開始入環的第一個節點。 如果連結串列無環,則返回 null。)
public class Solution { public ListNode detectCycle(ListNode head) { ListNode pNode = head; Set<ListNode> seen = new HashSet<ListNode>(); while (pNode != null) { if (seen.contains(pNode)) { return pNode; } else { seen.add(pNode); } pNode = pNode.next; } return null; } }
相交連結串列 (找到兩個單鏈表相交的起始節點。)
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode pNodeA = headA;
ListNode pNodeB = headB;
while (pNodeA != pNodeB) {
pNodeA = (pNodeA == null) ? headB : pNodeA.next;
pNodeB = (pNodeB == null) ? headA : pNodeB.next;
}
return pNodeA;
}
}
刪除連結串列的倒數第N個節點 (刪除連結串列的倒數第 n 個節點,並且返回連結串列的頭結點。)
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode first = head;
ListNode newNode = new ListNode(0,head); //啞節點 ,next指標域 指向連結串列的頭節點
ListNode pNode = newNode;
for (int i = 1; i <= n; ++i) {
first = first.next;
}
while (first != null) {
first = first.next;
pNode = pNode.next;
}
pNode.next = pNode.next.next;
return newNode.next;
}
}
用於解決連結串列中雙指標問題的模板
// Initialize slow & fast pointers
ListNode slow = head;
ListNode fast = head;
/**
* Change this condition to fit specific problem.
* Attention: remember to avoid null-pointer error
**/
while (slow != null && fast != null && fast.next != null) {
slow = slow.next; // move slow pointer one step each time
fast = fast.next.next; // move fast pointer two steps each time
if (slow == fast) { // change this condition to fit specific problem
return true;
}
}
return false; // change return value to fit specific problem
反轉連結串列
1 > 3 > 2 > null --> 2 > 2 > 1 > null
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode pNode = head;
while (pNode != null) {
ListNode newNode = pNode.next;
pNode.next = prev;
prev = pNode;
pNode = newNode;
}
return prev;
}
}
移除連結串列元素 (刪除連結串列中等於給定值 val 的所有節點。)
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode seen = new ListNode(0);
seen.next = head;
ListNode newNode = seen;
ListNode pNode = head;
while (pNode != null) {
if (pNode.val == val) {
newNode.next = pNode.next;
} else {
newNode = pNode;
}
pNode = pNode.next;
}
return seen.next;
}
}
奇偶連結串列 (給定一個連結串列 ,按順序將 奇數節點編號 和 偶數節點編號 放在一起)
1>2>4>5>8 -- > 1>4>8>2>5
class Solution {
public ListNode oddEvenList(ListNode head) {
if (head == null) {
return head;
}
ListNode evevNode = head.next;
ListNode newNode = head;
ListNode pNode = evevNode;
while (pNode != null && pNode.next != null) {
newNode.next = pNode.next;
newNode = newNode.next;
pNode.next = newNode.next;
pNode = pNode.next;
}
newNode.next = evevNode;
return head;
}
}
迴文連結串列 (判斷是否為迴文連結串列)
1>2>2>1
class Solution {
public boolean isPalindrome(ListNode head) {
Stack<Integer> cruu = new Stack<>();
ListNode pNode = head;
while (pNode != null) {
cruu.push(pNode.val);
pNode = pNode.next;
}
while (head != null) {
if (head.val != cruu.pop()) {
return false;
}
head = head.next;
}
return cruu.isEmpty();
}
}
合併兩個有序連結串列
從小到大
1:1>2>3>4>5>null
2:2>3>5>7>null
變成 :1>2>2>3>3>4>5>5>7>null
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode newNode = new ListNode(-1);
ListNode pNode = newNode;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
pNode.next = l1;
l1 = l1.next;
} else {
pNode.next = l2;
l2 = l2.next;
}
pNode = pNode.next;
}
// 有序的連結串列 ,最後只會剩一個沒有連線
// pNode的下一個節點引用 指向 如果 l1 == null 就指向 l2 ,否則 指向 l1 .
pNode.next = (l1 == null) ? l2 : l1;
return newNode.next;
}
}