/**
* 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 reverseList(ListNode head) {
ListNode cur = head;
ListNode pre = null;
ListNode next = null;
while (cur != null) {
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
}
/**
* 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 reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode p0 = dummy;
for (int i = 0; i < left - 1; i++) {
p0 = p0.next;
}
ListNode pre = null;
ListNode next = null;
ListNode cur = p0.next;
for (int i = 0; i < right - left + 1; i++) {
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
p0.next.next = cur;
p0.next = pre;
return dummy.next;
}
}
/**
* 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 reverseKGroup(ListNode head, int k) {
int n = 0;
ListNode cur = head;
while (cur != null) {
cur = cur.next;
n++;
}
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode p0 = dummy;
cur = p0.next;
ListNode pre = null;
ListNode next = null;
while (n >= k) {
n -= k;
for (int i = 0; i < k; i++) {
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
next = p0.next;
p0.next.next = cur;
p0.next = pre;
p0 = next;
}
return dummy.next;
}
}
课后作业:
延续上面的写法,创建哨兵节点p0,和反转K个group代码一模一样,就是k==2
time:O(n)
space:O(1)
/**
* 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 swapPairs(ListNode head) {
int n = 0;
ListNode cur = head;
while (cur != null) {
cur = cur.next;
n++;
}
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode p0 = dummy;
cur = p0.next;
ListNode pre = null;
ListNode next = null;
while (n >= 2) {
n -= 2;
for (int i = 0; i < 2; i++) {
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
next = p0.next;
p0.next.next = cur;
p0.next = pre;
p0 = next;
}
return dummy.next;
}
}
方法二:递归,感觉容易想一点
time: O(n),
space:O(n),递归需要 O(n)\mathcal{O}(n)O(n) 的栈空间
/**
* 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 swapPairs(ListNode head) {
if (head == null || head.next == null) return head;
ListNode newHead = head.next;
ListNode node = swapPairs(newHead.next);
newHead.next = head;
head.next = node;
return newHead;
}
}
方法1:可以用递归,也可用迭代
1.反转链表1
2.反转链表2
3.addTwo得到链表3
4.反转链表3
/**
* 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 addTwoNumbers(ListNode l1, ListNode l2) {
l1 = reverse(l1);
l2 = reverse(l2);
ListNode l3 = addTwo(l1, l2);
return reverse(l3);
}
private ListNode reverse(ListNode head) {
if (head == null || head.next == null) return head;
ListNode newHead = reverse(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
private ListNode addTwo(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
int carry = 0;
int sum = 0;
while (l1 != null && l2 != null) {
sum = l1.val + l2.val + carry;
carry = sum / 10;
cur.next = new ListNode(sum % 10);
cur = cur.next;
l1 = l1.next;
l2 = l2.next;
}
while (l1 != null) {
sum = l1.val + carry;
carry = sum / 10;
cur.next = new ListNode(sum % 10);
cur = cur.next;
l1 = l1.next;
}
while (l2 != null) {
sum = l2.val + carry;
carry = sum / 10;
cur.next = new ListNode(sum % 10);
cur = cur.next;
l2 = l2.next;
}
if (carry != 0) {
cur.next = new ListNode(carry);
}
return dummy.next;
}
}
方法2:用stack
两个stack,其他和数组做法没啥区别
2816. 翻倍以链表形式表示的数字 - 力扣(LeetCode)
直接用445的代码就行
/**
* 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 doubleIt(ListNode head) {
head = reverse(head);
ListNode res = addTwo(head, head);
return reverse(res);
}
private ListNode reverse(ListNode head) {
if (head == null || head.next == null) return head;
ListNode newHead = reverse(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
private ListNode addTwo(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
int carry = 0;
int sum = 0;
while (l1 != null && l2 != null) {
sum = l1.val + l2.val + carry;
carry = sum / 10;
cur.next = new ListNode(sum % 10);
cur = cur.next;
l1 = l1.next;
l2 = l2.next;
}
while (l1 != null) {
sum = l1.val + carry;
carry = sum / 10;
cur.next = new ListNode(sum % 10);
cur = cur.next;
l1 = l1.next;
}
while (l2 != null) {
sum = l2.val + carry;
carry = sum / 10;
cur.next = new ListNode(sum % 10);
cur = cur.next;
l2 = l2.next;
}
if (carry != 0) {
cur.next = new ListNode(carry);
}
return dummy.next;
}
}