- 两数相加
描述:给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头
题解:
/**
1. Definition for singly-linked list.
2. public class ListNode {
3. int val;
4. ListNode next;
5. ListNode() {}
6. ListNode(int val) { this.val = val; }
7. ListNode(int val, ListNode next) { this.val = val; this.next = next; }
8. }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode pre = new ListNode(0);
ListNode cur = pre;
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;
carry = sum / 10;
sum = sum % 10;
cur.next = new ListNode(sum);
cur = cur.next;
if(l1 != null)
l1 = l1.next;
if(l2 != null)
l2 = l2.next;
}
if(carry == 1) {
cur.next = new ListNode(carry);
}
return pre.next;
}
}
2. 删除链表的倒数第 N 个结点
描述:删除链表的倒数第 n 个结点,并且返回链表的头结点。
题解:
/**
1. Definition for singly-linked list.
2. public class ListNode {
3. int val;
4. ListNode next;
5. ListNode() {}
6. ListNode(int val) { this.val = val; }
7. ListNode(int val, ListNode next) { this.val = val; this.next = next; }
8. }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode pre = new ListNode(0);
pre.next = head;
ListNode start = pre, end = pre;
while(n != 0) {
start = start.next;
n--;
}
while(start.next != null) {
start = start.next;
end = end.next;
}
end.next = end.next.next;
return pre.next;
}
}
3. 合并两个有序链表
描述:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
题解:
/**
1. Definition for singly-linked list.
2. public class ListNode {
3. int val;
4. ListNode next;
5. ListNode() {}
6. ListNode(int val) { this.val = val; }
7. ListNode(int val, ListNode next) { this.val = val; this.next = next; }
8. }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1 == null) {
return l2;
}
if(l2 == null) {
return l1;
}
if(l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
4. 两两交换链表相邻的值
描述:给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。不只是单纯的改变节点内部的值,而是需要实际的进行节点交换
题解:
/**
1. Definition for singly-linked list.
2. public class ListNode {
3. int val;
4. ListNode next;
5. ListNode() {}
6. ListNode(int val) { this.val = val; }
7. ListNode(int val, ListNode next) { this.val = val; this.next = next; }
8. }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null) {
return head;
}
//假设链表为1>2>3>4
//定义新节点,存储第二个原节点2
ListNode newHead = head.next;
//头节点指向三四节点递归后的,即1>3>4
head.next = swapPairs(newHead.next);
//2指向头节点,即2>1>3>4
newHead.next = head;
return newHead;
}
}
5. 旋转链表
描述:给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
题解:
/**
* 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 rotateRight(ListNode head, int k) {
if(head == null || head.next == null || k==0) return head;
//计算链表的长度,顺便得到链表的最后一个节点
ListNode cur = head;
int len = 1;
while (cur.next != null) {
len++;
cur = cur.next;
}
//和第三种解法一样,对于k超过链表长度的问题,直接取模即可
int index = len - (k % len) - 1;
//最后一个节点指向头节点,形成环
cur.next = head;
//来到重新组装链表的位置
for (int i = 0; i < index; i++) {
head = head.next;
}
//head的next节点便是新的头节点,head自身便是尾节点
ListNode newHead = head.next;
//断开头尾节点
head.next = null;
return newHead;
}
}