我是
方圓
。
“無他,唯手熟爾”
2. 兩數相加
給出兩個 非空 的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式存儲的,並且它們的每個節點只能存儲 一位 數字。
如果,我們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。
您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。
示例:
輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
原因:342 + 465 = 807
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//神奇的預先指針
ListNode pre = new ListNode(0);
//當前位置
ListNode cur = pre;
//進位默認取0
int carry = 0;
while(l1 != null || l2 != null) {
int x = l1 == null ? 0 : l1.val;
int y = l2 == null ? 0 : l2.val;
int sum = x + y + carry;
//進位爲1,不進位爲0
carry = sum / 10;
//求出當前位上的數
sum = sum % 10;
//將當前數放在鏈表上
cur.next = new ListNode(sum);
//當前位置後移一位
cur = cur.next;
//不等於null時才能繼續向前移動
if(l1 != null)
l1 = l1.next;
if(l2 != null)
l2 = l2.next;
}
//這一步千萬別忘了,當最後一次求和要進位不要遺漏
if(carry == 1) {
cur.next = new ListNode(carry);
}
//返回預先指針的下一個節點即爲所求
return pre.next;
}
}
19. 刪除鏈表的倒數第N個節點
給定一個鏈表,刪除鏈表的倒數第 n 個節點,並且返回鏈表的頭結點。
示例:
給定一個鏈表: 1->2->3->4->5, 和 n = 2.
當刪除了倒數第二個節點後,鏈表變爲 1->2->3->5.
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
//神奇的預先指針
ListNode pre = new ListNode(0);
//指向頭節點
pre.next = head;
//定義兩個指針
ListNode start = pre;
ListNode end = pre;
//先讓start指針移動n次,以示意爲例,應移動到2
//此時end指針和start指針相隔兩個節點
while(n != 0){
start = start.next;
n--;
}
//讓start移動到最後
//那麼end則會移動到3節點的位置
//end的下一個節點即爲要刪除的節點
while(start.next != null){
start = start.next;
end = end.next;
}
//讓end的下一個節點爲下下個節點,即可刪除
end.next = end.next.next;
return pre.next;
}
}
61. 旋轉鏈表
給定一個鏈表,旋轉鏈表,將鏈表每個節點向右移動 k 個位置,其中 k 是非負數。
示例1:
輸入: 1->2->3->4->5->NULL, k = 2
輸出: 4->5->1->2->3->NULL
解釋:
向右旋轉 1 步: 5->1->2->3->4->NULL
向右旋轉 2 步: 4->5->1->2->3->NULL
示例2:
輸入: 0->1->2->NULL, k = 4
輸出: 2->0->1->NULL
解釋:
向右旋轉 1 步: 2->0->1->NULL
向右旋轉 2 步: 1->2->0->NULL
向右旋轉 3 步: 0->1->2->NULL
向右旋轉 4 步: 2->0->1->NULL
class Solution {
public ListNode rotateRight(ListNode head, int k) {
//先判空
if(head == null) return null;
if(head.next == null) return head;
//先找到舊的尾巴,並讓頭尾相連
ListNode old_tail = head;
int n = 1;//用n表示鏈表長度
while(old_tail.next != null){
old_tail = old_tail.next;
n++;
}
old_tail.next = head;//頭尾相連
//找到新的尾巴
ListNode new_tail = head;
//解釋一下這裏爲什麼k%n,在k<n的時候,新尾巴的位置爲n-k-1
//當k>n的時候需要進行k%n運算,去掉整圈數
for(int i = 0;i < n - k % n - 1;i++){
new_tail = new_tail.next;
}
//新的頭爲新的尾巴的下一位
ListNode new_head = new_tail.next;
//新的尾巴的下一位要爲null才能成爲尾巴
new_tail.next = null;
return new_head;
}
}
138. 複製帶隨機指針的鏈表
給定一個鏈表,每個節點包含一個額外增加的隨機指針,該指針可以指向鏈表中的任何節點或空節點。
要求返回這個鏈表的 深拷貝。
我們用一個由 n 個節點組成的鏈表來表示輸入/輸出中的鏈表。每個節點用一個 [val, random_index] 表示:
- val:一個表示 Node.val 的整數。
- random_index:隨機指針指向的節點索引(範圍從 0 到 n-1);如果不指向任何節點,則爲 null 。
示例 1:
輸入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
輸出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
class Solution {
//創建一個HashMap,將訪問過的節點放進去
//泛型兩個Node,左側Node爲head鏈表,右側爲深拷貝的鏈表
HashMap<Node,Node> visitedHash = new HashMap<Node,Node>();
public Node copyRandomList(Node head) {
//先判空
if(head == null){
return null;
}
//如果這個節點存在HaspMap中,直接返回這個節點
if(this.visitedHash.containsKey(head)){
return this.visitedHash.get(head);
}
//如果沒有這個節點,則創建一個新的節點
Node node = new Node(head.val);
//存入HashMap中
visitedHash.put(head,node);
//遞歸算法
node.next = copyRandomList(head.next);
node.random = copyRandomList(head.random);
return node;
}
}
206. 反轉鏈表
反轉一個鏈表。
實例:
輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur = head;
ListNode pre = new ListNode(0);
ListNode tem = null;
while(cur != null){
tem = cur.next;
cur.next = pre.next;
pre.next = cur;
cur = tem;
}
return pre.next;
}
}