继上篇:
- 删除 val的值、有序合并两个链表(从小到大)
class Node {
int val;
Node next = null;
public Node(int val) {
this.val = val;
}
}
public class Solution {
//删除 val的值
Node removeAll(Node head, int val) {
Node prev = null;
Node cur = head;
while (cur != null) {
if (cur.val == val) {
if (cur == head) {
head = cur.next;
} else {
prev.next = cur.next;
}
} else {
prev = cur;
}
cur = cur.next;
}
return head;
}
//有序合并两个链表(从小到大)
Node merge(Node head1, Node head2) {
if (head1 == null) {
return head2;
}
if (head2 == null) {
return head1;
}
Node result = null;
Node last = null;
Node cur1 = head1;
Node cur2 = head2;
while (cur1 != null && cur2 != null) {
if (cur1.val <= cur2.val) {
if (result == null) {
result = cur1;
} else {
last.next = cur1;
}
last = cur1;
cur1 = cur1.next;
} else {
if (result == null) {
result = cur2;
} else {
last.next = cur2;
}
last = cur2;
cur2 = cur2.next;
}
}
if (cur1 != null) {
last.next = cur1;
} else {
last.next = cur2;
}
return result;
}
public static Node createList() {
Node n1 = new Node(6);
Node n3 = new Node(2);
Node n4 = new Node(6);
Node n6 = new Node(4);
Node n8 = new Node(6);
n1.next = n3;
n3.next = n4;
n4.next = n6;
n6.next = n8;
return n1;
}
public static Node createList1() {
Node n1 = new Node(1);
Node n2 = new Node(2);
n1.next = n2;
return n1;
}
public static Node createList2() {
Node n1 = new Node(1);
Node n2 = new Node(3);
Node n3 = new Node(5);
Node n4 = new Node(7);
n1.next = n2;
n2.next = n3;
n3.next = n4;
return n1;
}
public static void main(String[] args) {
Node head = createList();
Node result = new Solution().removeAll(head, 6);
for (Node cur = result; cur != null; cur = cur.next) {
System.out.println(cur.val);
}
System.out.println("=====================");
Node head1 = createList1();
Node head2 = createList2();
Node merged = new Solution().merge(head1, head2);
for (Node cur = merged; cur != null; cur = cur.next) {
System.out.println(cur.val);
}
}
}
- 给定一个 val 值,链表中小于 val 的值放在左边,大于 val 的值放在右边,返回头结点 head
class ListNode {
public int val;
public ListNode next;
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
public ListNode(int val) {
this(val, null);
}
}
public class LinkedListInterview {
//给定一个 val 值,链表中小于 val 的值放在左边,大于 val 的值放在右边,返回头结点 head
public ListNode separateByX(ListNode head, int x) {
/*
遍历整个链表,把小于 x 的尾插到一个小链表
把大于等于 x 的尾插到一个大链表中
理想情况下,把大链表接到小链表后边
1) 如果没有小链表,直接返回大链表(大链表可能为空)
保证,返回链表的最后一个结点.next == null
sEnd / bEnd
*/
/* 尾插
1. 先情况讨论:
1)如果当前链表为空,要插入的结点就是链表的第一个结点
2) 如果链表不为空,
1. 先找到当前的最后一个结点
2. 让当前的最后一个结点的 next = 要插入的结点
3. 如果每次的最后一个结点都是我们插入的
可以记录上次插入的最后一个结点
4. 不要忘记更新最后一个结点
*/
ListNode sHead = null;// 指向小链表的第一个结点
ListNode sEnd = null;// 记录小链表的最后一个结点
ListNode bHead = null;
ListNode bEnd = null;
for (ListNode cur = head; cur != null; cur = cur.next) {
if (cur.val < x) {
/* 尾插到小的链表中 */
if (sHead == null) {
sHead = cur;
} else {
sEnd.next = cur;
}
sEnd = cur;
} else {
/* 尾插到大的链表中 */
// 同理
if (bHead == null) {
bHead = cur;
} else {
bEnd.next = cur;
}
bEnd = cur;
}
}
if (sEnd == null) {
return bHead;
}
sEnd.next = bHead;
if (bEnd != null) {
bEnd.next = null;
}
return sHead;
}
private static ListNode createTestList() {
ListNode n1 = new ListNode(4);
ListNode n2 = new ListNode(5);
ListNode n3 = new ListNode(2);
ListNode n4 = new ListNode(7);
ListNode n5 = new ListNode(6);
ListNode n6 = new ListNode(3);
ListNode n7 = new ListNode(8);
ListNode n8 = new ListNode(1);
n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = n6;
n6.next = n7;
n7.next = n8;
return n1;
}
private static void test() {
// 4 5 2 7 6 3 8 1
ListNode head = createTestList();
ListNode result = new LinkedListInterview().separateByX(head, 5);
// 4 2 3 1 5 7 6 8
for (ListNode cur = result; cur != null; cur = cur.next) {
System.out.println(cur.val);
}
}
public static void main(String[] args) {
test();
}
}
- 复杂链表的深度复制
public class Solution {
CNode copy(CNode head) {
if (head == null) {
return null;
}
CNode p1 = head;
while (p1 != null) {
CNode p2 = new CNode(p1.val);
p2.next = p1.next;
p1.next = p2;
p1 = p2.next;
}
p1 = head;
while (p1 != null) {
CNode p2 = p1.next;
if (p1.random != null) {
p2.random = p1.random.next;
}
p1 = p2.next;
}
p1 = head;
CNode newHead = head.next;
while (p1 != null) {
CNode p2 = p1.next;
p1.next = p2.next;
if (p2.next != null) {
p2.next = p2.next.next;
}
p1 = p1.next;
}
return newHead;
}
}
//psvm
public static void main(String[] args) {
Solution solution = new Solution();
testComplexListCopy(solution);
//testReverseList();
//testRemoveAll();
}
private static void testComplexListCopy(Solution solution) {
// 1. 构建测试数据
CNode head = createComplexList1();
// 2. 进行测试
CNode resultHead = solution.copy(head);
// 3. 对测试结果进行打印
printCList(resultHead);
}
// CNode 必须有一个构造方法,形参是 int val
// 并且,初始化后,next 和 random 都是 null
private static CNode createComplexList1() {
CNode n1 = new CNode(1);
CNode n2 = new CNode(2);
CNode n3 = new CNode(3);
CNode n4 = new CNode(4);
n1.random = n3; n2.random = n1; n3.random = n3;
n1.next = n2; n2.next = n3; n3.next = n4;
return n1;
}
// CNode 必须实现一个 String toString() 方法
//打印
private static void printCList(CNode head) {
for (CNode cur = head; cur != null; cur = cur.next) {
System.out.print(cur + " --> ");
}
System.out.println();
}