4、在链表中穿针引线
1、在节点间穿针引线
/**
* 非递归实现
* 最终状态如下
* cur、next -> null
* prev -> newHead
*/
public static ListNode reverseList1(ListNode head) {
ListNode prev = null;
ListNode cur = head;
ListNode next;
while (cur != null) {
next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
}
return prev;
}
/**
* 递归: 反转以 head 为头的链表, 并返回新的头结点
*/
public static ListNode reverseList2(ListNode head) {
if (head == null || head.next == null) return head;
ListNode newHead = reverseList2(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
更多问题
92 - 反转链表 II
2、测试你的链表程序
public class ListNode {
public int val;
public ListNode next;
public ListNode() {
}
public ListNode(int val) {
this(val, null);
}
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
public ListNode(int[] arr) {
if (arr == null || arr.length == 0) throw new IllegalArgumentException("Arr is empty.");
this.val = arr[0];
ListNode cur = this;
for (int i = 1; i < arr.length; i++) {
cur.next = new ListNode(arr[i]);
cur = cur.next;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
ListNode cur = this;
while (cur != null) {
sb.append(cur.val).append("->");
cur = cur.next;
}
sb.append("NULL");
return sb.toString();
}
}
更多问题
83 - 删除排序链表中的重复元素
86 - 分隔链表
328 - 奇偶链表
2 - 两数相加
445 - 两数相加 II
3、设立链表的虚拟头结点
/**
* 不使用 dummyHead
*/
public static ListNode removeElements1(ListNode head, int val) {
// 1.先删除符合条件的头结点
while (head != null && head.val == val) head = head.next;
if (head == null) return null;
// 2.再删除其他节点
ListNode prev = head;
while (prev.next != null) {
if (prev.next.val == val) prev.next = prev.next.next;
else prev = prev.next;
}
return head;
}
/**
* 使用 dummyHead
*/
public static ListNode removeElements2(ListNode head, int val) {
ListNode dummyHead = new ListNode(-1, head);
ListNode prev = dummyHead;
while (prev.next != null) {
if (prev.next.val == val) prev.next = prev.next.next;
else prev = prev.next;
}
return dummyHead.next;
}
/**
* 递归解决问题
*/
public static ListNode removeElements3(ListNode head, int val) {
if (head == null) return null;
head.next = removeElements3(head.next, val);
return head.val == val ? head.next : head;
}
4、复杂的穿针引线
public static ListNode swapPairs1(ListNode head) {
if (head == null || head.next == null) return head;
ListNode dummyHead = new ListNode(-1, head);
// 1 -> 2 -> 3 -> 4 -> 5 -> 6
// 2 -> 1 -> 4 -> 3 -> 6 -> 5
ListNode prev = dummyHead;
ListNode node1 = head;
ListNode node2 = head.next;
ListNode next;
while (node1 != null && node2 != null) {
next = node2.next;
node2.next = node1;
node1.next = next;
prev.next = node2;
prev = node1;
node1 = next;
if (node1 != null) node2 = node1.next;
}
return dummyHead.next;
}
public static ListNode swapPairs2(ListNode head) {
if (head == null || head.next == null) return head;
// 1 -> 2 -> 3 -> 4 -> 5 -> 6
// 2 -> 1 -> 4 -> 3 -> 6 -> 5
ListNode node = swapPairs2(head.next.next);
ListNode newHead = head.next;
newHead.next = head;
head.next = node;
return newHead;
}
5、不仅仅是穿针引线
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
6、双指针技术
public static ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyHead = new ListNode(-1, head);
ListNode p = dummyHead;
ListNode q = p;
// 让 q 向后移动 n + 1 次
for (int i = 0; i < n + 1; i++) {
if (q == null) return head;
q = q.next;
}
while (q != null) {
p = p.next;
q = q.next;
}
p.next = p.next.next;
return dummyHead.next;
}
本文来自博客园,作者:lidongdongdong~,转载请注明原文链接:https://www.cnblogs.com/lidong422339/p/17389958.html