Add Two Numbers 需要注意的点是当两个数相加大于等于10时:1如果发生在list中间,则将该数加入下一步运算(这一步在3个while loop里都体现)。2发生在list已经跑完了,要注意check其是否不为0,如果满足,则要新建node将其加入list。
class Solution {
public ListNode addTwoNumbers ( ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode ( 0 ) ;
int carry = 0 ;
int num;
ListNode prv = dummyHead;
while ( l1 != null && l2 != null) {
num = ( l1. val + l2. val + carry) % 10 ;
ListNode cur = new ListNode ( num) ;
prv. next = cur;
prv = cur;
carry = ( l1. val + l2. val + carry) / 10 ;
l1 = l1. next;
l2 = l2. next;
}
while ( l1 != null) {
num = ( carry + l1. val) % 10 ;
carry = ( carry + l1. val) / 10 ;
ListNode cur = new ListNode ( num) ;
prv. next = cur;
prv = cur;
l1 = l1. next;
}
while ( l2 != null) {
num = ( carry + l2. val) % 10 ;
carry = ( carry + l2. val) / 10 ;
ListNode cur = new ListNode ( num) ;
prv. next = cur;
prv = cur;
l2 = l2. next;
}
if ( carry != 0 ) {
ListNode cur = new ListNode ( carry) ;
prv. next = cur;
}
return dummyHead. next;
}
}
Remove Nth Node From End of List key idea:将list反转,找到第k个node,删除, 再反转list。需要注意第是k 可能reversed list’s head,所以要用一个dummy node来指向reversed head,以防止其被删除后,丢失head。
class Solution {
public ListNode removeNthFromEnd ( ListNode head, int n) {
if ( head == null || head. next == null) {
return null;
}
ListNode reversedHead = reverseNode ( head) ;
ListNode dummy = new ListNode ( ) ;
dummy. next = reversedHead;
ListNode cur = dummy;
for ( int i = 0 ; i < n - 1 ; i++ ) {
cur = cur. next;
}
cur. next = cur. next. next;
ListNode newHead = reverseNode ( dummy. next) ;
return newHead;
}
public ListNode reverseNode ( ListNode head) {
if ( head == null) {
return null;
}
ListNode prev = null;
ListNode cur = head;
while ( cur != null) {
ListNode temp = cur. next;
cur. next = prev;
prev = cur;
cur = temp;
}
return prev;
}
}
Swap Nodes in Pairs 用了recursive来做,base case是当head为null或者next为null(落单的node)时返回。然后做简单的反转,并将反转后右边的node跟从下一层传来的node链接起来,并将自己反转后左边的node返回(这样上一层的node来链接它)
class Solution {
public ListNode swapPairs ( ListNode head) {
if ( head == null || head. next == null) {
return head;
}
ListNode newHead = helper ( head) ;
return newHead;
}
public ListNode helper ( ListNode head) {
if ( head == null || head. next == null) {
return head;
}
ListNode newHead = helper ( head. next. next) ;
ListNode temp = head. next;
head. next. next = head;
head. next = newHead;
return temp;
}
}
Reverse Nodes in k-Group 更上一题几乎一样。只是base case是只要剩余的node小于k个,则返回在这一层的head,也就是为newhead。在做反转的时候,可以把newhead想象为prev node。反转完后将prev,也就是newhead返回到上一层。
class Solution {
public ListNode reverseKGroup ( ListNode head, int k) {
ListNode newHead = helper ( head, k) ;
return newHead;
}
public ListNode helper ( ListNode head, int k) {
ListNode passNode = head;
for ( int i = 0 ; i < k; i++ ) {
if ( passNode == null) {
return head;
}
passNode = passNode. next;
}
ListNode newHead = reverseKGroup ( passNode, k) ;
ListNode prev = newHead;
ListNode curr = head;
for ( int i = 0 ; i < k; i++ ) {
ListNode temp = curr. next;
curr. next = prev;
prev = curr;
curr = temp;
}
return prev;
}
}
Rotate List key idea是将list反转,然后找到第k个和第k + 1个node,产生两个list,第一个list的head就是reversed head,第二个list的head是第k+1个node。然后注意要将第k个node跟后面断开。再反转两个lists,再链接。
class Solution {
public ListNode rotateRight ( ListNode head, int k) {
if ( head == null || head. next == null) {
return head;
}
ListNode countNode = head;
int count = 0 ;
while ( countNode != null) {
countNode = countNode. next;
count++ ;
}
k = k % count;
if ( k == 0 ) {
return head;
}
ListNode tempHead = reverse ( head) ;
ListNode curr = tempHead;
ListNode prev = null;
for ( int i = 0 ; i < k; i++ ) {
prev = curr;
curr = curr. next;
}
prev. next = null;
ListNode newHead1 = reverse ( tempHead) ;
ListNode newHead2 = reverse ( curr) ;
ListNode tail = newHead1;
for ( int i = 0 ; i < k - 1 ; i++ ) {
tail = tail. next;
}
tail. next = newHead2;
return newHead1;
}
public ListNode reverse ( ListNode head) {
if ( head == null || head. next == null) {
return head;
}
ListNode prev = null;
ListNode curr = head;
while ( curr != null) {
ListNode temp = curr. next;
curr. next = prev;
prev = curr;
curr = temp;
}
return prev;
}
}
Remove Duplicates from Sorted List II 凡事出现重复的数都不留。所以不可以一上来就把node加进去。首先设置一个dummy node因为我们不再确定head是哪个node了。然后设置一个tail pointer。在while loop里面设置两个pointer一个slow,一个fast,凡事node的val相同,则fast后移。然后check fast与slow相差多少,如果为1,则说明该value是唯一的,则加入我们的list里,然后tail后移。
class Solution {
public ListNode deleteDuplicates ( ListNode head) {
if ( head == null || head. next == null) {
return head;
}
ListNode dummy = new ListNode ( 0 ) ;
ListNode tail = dummy;
ListNode fast = head;
while ( fast != null) {
int count = 0 ;
ListNode slow = fast;
while ( fast != null && slow. val == fast. val) {
count++ ;
fast = fast. next;
}
if ( count == 1 ) {
tail. next = slow;
tail = tail. next;
}
}
tail. next = null;
return dummy. next;
}
}
Remove Duplicates from Sorted List much easier version of previous one. lol. only for reference.
class Solution {
public ListNode deleteDuplicates ( ListNode head) {
if ( head == null || head. next == null) {
return head;
}
ListNode slow = head;
ListNode fast = head. next;
while ( fast != null) {
if ( fast. val == slow. val) {
fast = fast. next;
} else {
slow. next = fast;
slow = slow. next;
}
}
slow. next = null;
return head;
}
}
Partition List 因为list的head不确定,所以需要dummy head来接住。然后分别设置tail pointers,将符合条件的node分别接在tail后面,tail后移。注意链接两个lists的时候,需要将tail2.next指向null。
class Solution {
public ListNode partition ( ListNode head, int x) {
if ( head == null || head. next == null) {
return head;
}
ListNode dummy1 = new ListNode ( ) ;
ListNode dummy2 = new ListNode ( ) ;
ListNode tail1 = dummy1;
ListNode tail2 = dummy2;
while ( head != null) {
if ( head. val < x) {
tail1. next = head;
tail1 = tail1. next;
} else {
tail2. next = head;
tail2 = tail2. next;
}
head = head. next;
}
tail1. next = dummy2. next;
tail2. next = null;
return dummy1. next;
}
}