一. 力扣 2. 两数相加
1. 题目
2. 算法原理
3. 代码
java
public ListNode addTwoNumbers(ListNode cur1, ListNode cur2) {
ListNode newHead = new ListNode();
ListNode tail = newHead;
int tmp = 0;
while (cur1 != null && cur2 != null) {
tmp += (cur1.val + cur2.val);
ListNode node = new ListNode(tmp % 10);
tmp /= 10;
tail.next = node;
tail = node;
cur1 = cur1.next;
cur2 = cur2.next;
}
while (cur1 != null) {
tmp += cur1.val;
ListNode node = new ListNode(tmp % 10);
tmp /= 10;
tail.next = node;
tail = node;
cur1 = cur1.next;
}
while (cur2 != null) {
tmp += cur2.val;
ListNode node = new ListNode(tmp % 10);
tmp /= 10;
tail.next = node;
tail = node;
cur2 = cur2.next;
}
if ((tmp % 10) != 0) {
ListNode node = new ListNode(tmp % 10);
tail.next = node;
}
return newHead.next;
}
二. 力扣 24. 两两交换链表中的节点
1. 题目
2. 算法原理
3. 代码
java
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode newHead = new ListNode();
ListNode prev = newHead;
ListNode cur = head;
ListNode next = cur.next;
ListNode nnext = next.next;
while (cur != null && cur.next != null) {
prev.next = next;
next.next = cur;
cur.next = nnext;
if (nnext == null || nnext.next == null) {
break;
}
prev = cur;
cur = nnext;
next = nnext.next;
nnext = next.next;
}
return newHead.next;
}
三. 力扣 143. 重排链表
1. 题目
2. 算法原理
3. 代码
(1) 方法一:从中间点prev处开始逆序
java
public void reorderList(ListNode head) {
if (head == null || head.next == null || head.next.next == null) {
return;
}
ListNode prev = head;
ListNode cur = head;
// 寻找中间节点 prev
while (cur != null && cur.next != null) {
cur = cur.next.next;
prev = prev.next;
}
// 逆序头插法
ListNode mid = prev;
cur = prev;
prev = null;
while (cur != null) {
ListNode curN = cur.next;
cur.next = prev;
prev = cur;
cur = curN;
}
// 交替合并
// 逆序后的 头结点是 prev
ListNode cur1 = head;
ListNode cur2 = prev;
cur = new ListNode();
while (cur1 != mid && cur2 != null) {
cur.next = cur1;
cur = cur.next;
cur1 = cur1.next;
cur.next = cur2;
cur = cur.next;
cur2 = cur2.next;
}
}
(2) 方法二:从中间点next处开始逆序
java
public void reorderList(ListNode head) {
if (head == null || head.next == null || head.next.next == null) {
return;
}
ListNode prev = head;
ListNode cur = head;
// 寻找中间节点 prev
while (cur != null && cur.next != null) {
cur = cur.next.next;
prev = prev.next;
}
// 逆序头插法
cur = prev.next;
prev.next = null;
prev = null;
while (cur != null) {
ListNode curN = cur.next;
cur.next = prev;
prev = cur;
cur = curN;
}
// 交替合并
// 逆序后的 头结点是 prev
ListNode cur1 = head;
ListNode cur2 = prev;
cur = new ListNode();
while (cur1 != null) {
cur.next = cur1;
cur = cur.next;
cur1 = cur1.next;
if (cur2 != null) {
cur.next = cur2;
cur = cur.next;
cur2 = cur2.next;
}
}
}
四. 力扣 23. 合并 K 个升序链表
1. 题目
这道题目就是把多个有序链表连接成一个, 这里不过多赘述题意, 直接上算法原理
2. 算法原理
(1) 算法一:堆排序求解
这里可以用优先级队列, 通过建立小根堆的方法来进行链接
(2) 算法二:递归分治解法
该解法与归并排序分治的解法思路类似,只是把对两个数组合并的过程变成了两个链表合并
3. 代码
(1) 方法一代码
java
// 堆排序做法
public ListNode mergeKLists(ListNode[] lists) {
ListNode newHead = new ListNode();
ListNode cur = newHead;
PriorityQueue<ListNode> priorityQueue = new PriorityQueue<>((v1,v2) -> v1.val - v2.val);
for(ListNode head : lists) {
if (head != null) {
priorityQueue.offer(head);
}
}
// 取出头结点, 并合并
while (!priorityQueue.isEmpty()) {
cur.next = priorityQueue.poll();
cur = cur.next;
if (cur.next != null) {
priorityQueue.offer(cur.next);
}
}
return newHead.next;
}
(2) 方法二代码
java
public ListNode mergeKLists(ListNode[] lists) {
int n = lists.length;
if (n == 0) {
return null;
}
return merge(lists, 0, n - 1);
}
public ListNode merge(ListNode[] lists, int s, int e) {
if (s >= e) {
return lists[s];
}
int mid = (s + e) / 2;
// 左面合并
ListNode left = merge(lists,s,mid);
// 右面合并
ListNode right = merge(lists,mid + 1, e);
// 合并两个有序链表
return sort(left,right);
}
public ListNode sort(ListNode cur1, ListNode cur2) {
ListNode newHead = new ListNode();
ListNode cur = newHead;
while (cur1 != null && cur2 != null) {
if (cur1.val <= cur2.val) {
cur.next = cur1;
cur1 = cur1.next;
}else {
cur.next = cur2;
cur2 = cur2.next;
}
cur = cur.next;
}
if (cur1 != null) {
cur.next = cur1;
}
if (cur2 != null) {
cur.next = cur2;
}
return newHead.next;
}
五. 力扣 25. K 个一组翻转链表
1. 题目
题目意思是每k个节点进行逆序,不满足k个节点的不逆序
2. 算法原理
3. 代码
java
public ListNode reverseKGroup(ListNode head, int k) {
ListNode cur = head;
int n = 0;
while (cur != null) {
n++;
cur = cur.next;
}
n = n / k;
cur = head;
ListNode newHead = new ListNode();
ListNode prev = newHead;
for (int i = 0; i < n; i++) {
ListNode tmp = cur;
for (int j = 0; j < k; j++) {
ListNode next = cur.next;
cur.next = prev.next;
prev.next = cur;
cur = next;
}
prev = tmp;
}
prev.next = cur;
return newHead.next;
}