反转单链表或双向链表
class Solution {
public static class Node {
public int value
public Node next
public Node(int data) {
this.value = data
}
}
// 反转单链表
public Node reverseList(Node head) {
Node pre = null
Node next = null
while (head != null){
next = head.next
head.next = pre
pre = head
head = next
}
return pre
}
public static class DoubleNode {
public int value
public DoubleNode last
public DoubleNode next
public DoubleNode(int data) {
this.value = data
}
}
// 反转双向链表
public static DoubleNode reverseList(DoubleNode head) {
DoubleNode pre = null
DoubleNode next = null
while (head != null) {
next = head.next
head.next = pre
head.last = next
pre = head
head = next
}
return pre
}
}
打印两个有序链表的公共部分
public class Code03_PrintCommonPart {
public static class Node {
public int value
public Node next
public Node(int data) {
this.value = data
}
}
public static void printCommonPart(Node head1, Node head2) {
System.out.print("Common Part: ")
while (head1 != null && head2 != null) {
if (head1.value < head2.value) {
head1 = head1.next
} else if (head1.value > head2.value) {
head2 = head2.next
} else {
System.out.print(head1.value + " ")
head1 = head1.next
head2 = head2.next
}
}
System.out.println()
}
public static void printLinkedList(Node node) {
System.out.print("Linked List: ")
while (node != null) {
System.out.print(node.value + " ")
node = node.next
}
System.out.println()
}
public static void main(String[] args) {
Node node1 = new Node(2)
node1.next = new Node(3)
node1.next.next = new Node(5)
node1.next.next.next = new Node(6)
Node node2 = new Node(1)
node2.next = new Node(2)
node2.next.next = new Node(5)
node2.next.next.next = new Node(7)
node2.next.next.next.next = new Node(8)
printLinkedList(node1)
printLinkedList(node2)
printCommonPart(node1, node2)
}
}
判断一个链表是否为回文结构
class Solution {
public static class Node {
public int value
public Node next
public Node(int data) {
this.value = data
}
}
// 把所有节点先全部都放到栈里,再一个个去对比判断相等
public static boolean isPalindrome1(Node head) {
Stack<Node> stack = new Stack<>()
Node cur = head
while (cur != null){
stack.push(cur)
cur = cur.next
}
while (head != null){
if (head.value != stack.pop().value) return false
head = head.next
}
return true
}
// 用快慢指针只把一半的节点放进栈中,然后从头对比
public static boolean isPalindrome2(Node head) {
if(head == null || head.next == null) return true
Node fast = head
Node slow = head.next
while (fast.next != null && fast.next.next != null){
slow = slow.next
fast = fast.next.next
}
Stack<Node> stack = new Stack<>()
while (slow != null){
stack.push(slow)
slow = slow.next
}
while (!stack.isEmpty()){
if (head.value != stack.pop().value) return false
head = head.next
}
return true
}
// 只用三个变量 不用其他辅助空间,空间复杂度O(1)
public static boolean isPalindrome3(Node head) {
if(head == null || head.next == null) return true
Node n1 = head
Node n2 = head
// 此时n1在链表的中点,n2为右半部分的第一个节点
while (n2.next != null && n2.next.next != null){
n1 = n1.next
n2 = n2.next.next
}
// 翻转右半部分
n2 = n1.next
Node n3 = null
n1.next = null
while (n2 != null){
n3 = n2.next
n2.next = n1
n1 = n2
n2 = n3
}
// 从左右半部分的两头开始对比判断 n1为右半部分的最后一个节点
n3 = n1
n2 = head
boolean result = true
while (n1 != null && n2 != null){
if (n1.value != n2.value){
result = false
break
}
n1 = n1.next
n2 = n2.next
}
// 最后把翻转的右半部分再复原
n1 = n3.next
n3.next = null
while (n1 != null){
n2 = n1.next
n1.next = n3
n3 = n1
n1 = n2
}
return result
}
public static void printLinkedList(Node node) {
System.out.print("Linked List: ")
while (node != null) {
System.out.print(node.value + " ")
node = node.next
}
System.out.println()
}
public static void main(String[] args) {
Node head = null
printLinkedList(head)
System.out.print(isPalindrome1(head) + " | ")
System.out.print(isPalindrome2(head) + " | ")
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(2);
head.next.next.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(2);
head.next.next.next.next = new Node(1);
printLinkedList(head);
System.out.print(isPalindrome1(head) + " | ");
System.out.print(isPalindrome2(head) + " | ");
System.out.println(isPalindrome3(head) + " | ");
printLinkedList(head);
System.out.println("=========================");
}
}
将单向链表按某值划分成左边小,中间相等,右边大的形式
class Solution {
public static class Node {
public int value
public Node next
public Node(int data) {
this.value = data
}
}
public static Node listPartition1(Node head, int pivot) {
if (head == null) return head
// i为节点总数,把所有节点放到help数组中
int i = 0
Node cur = head
while (cur != null){
i++
cur = cur.next
}
Node[] help = new Node[i]
i = 0
cur = head
for (i = 0
help[i] = cur
cur = cur.next
}
arrPartition(help,pivot)
//把排序好的help数组节点再恢复成链表
for (int j = 1
help[j - 1].next = help[j]
}
help[help.length - 1].next = null
return help[0]
}
//通过荷兰国旗的方式排序
public static void arrPartition(Node[] help, int pivot) {
int small = -1
int big = help.length
int index = 0
while (index != big){
if (help[index].value < pivot){
swap(help,++small,index++)
}else if (help[index].value > pivot){
swap(help,--big,index)
}else {
index++
}
}
}
public static Node listPartition2(Node head, int pivot) {
Node sH = null
Node sT = null
Node eH = null
Node eT = null
Node bH = null
Node bT = null
Node next = null
// every node distributed to three lists
while (head != null) {
next = head.next
head.next = null
if (head.value < pivot) {
if (sH == null) {
sH = head
sT = head
} else {
sT.next = head
sT = head
}
} else if (head.value == pivot) {
if (eH == null) {
eH = head
eT = head
} else {
eT.next = head
eT = head
}
} else {
if (bH == null) {
bH = head
bT = head
} else {
bT.next = head
bT = head
}
}
head = next
}
// small and equal reconnect 如果有小于区域
if (sT != null) {
sT.next = eH
eT = eT == null ? sT : eT
}
// all reconnect
if (eT != null) {
eT.next = bH
}
return sH != null ? sH : eH != null ? eH : bH
}
public static void swap(Node[] nodeArr, int a, int b) {
Node tmp = nodeArr[a]
nodeArr[a] = nodeArr[b]
nodeArr[b] = tmp
}
public static void printLinkedList(Node node) {
System.out.print("Linked List: ")
while (node != null) {
System.out.print(node.value + " ")
node = node.next
}
System.out.println()
}
public static void main(String[] args) {
Node head1 = new Node(7)
head1.next = new Node(9)
head1.next.next = new Node(1)
head1.next.next.next = new Node(8)
head1.next.next.next.next = new Node(5)
head1.next.next.next.next.next = new Node(2)
head1.next.next.next.next.next.next = new Node(5)
printLinkedList(head1)
// head1 = listPartition1(head1, 4)
head1 = listPartition2(head1, 5)
printLinkedList(head1)
}
}
复制含有随机指针节点的链表
public class Solution {
public static class Node {
public int value
public Node next
public Node rand
public Node(int data) {
this.value = data
}
}
// 用哈希表存储key为老节点 value为新节点
public static Node copyListWithRand1(Node head) {
HashMap<Node,Node> hashMap = new HashMap<>()
Node cur = head
while (cur != null){
hashMap.put(cur,new Node(cur.value))
cur = cur.next
}
cur = head
while (cur != null){
hashMap.get(cur).next = hashMap.get(cur.next)
hashMap.get(cur).rand = hashMap.get(cur.rand)
cur = cur.next
}
return hashMap.get(head)
}
public static Node copyListWithRand2(Node head) {
if (head == null) return head
// 现在每个老节点后边复制一个新节点 1->1`->2->2`->3....
Node cur = head
Node next = null
while (cur != null){
next = cur.next
cur.next = new Node(cur.value)
cur.next.next = next
cur = next
}
// 处理新节点的rand
cur = head
Node curCopy = null
while (cur != null){
next = cur.next.next
curCopy = cur.next
curCopy.rand = cur.rand != null ? cur.rand.next : null
cur = next
}
// 再把老节点和新节点再分别拆开
Node result = head.next
cur = head
while (cur != null){
next = cur.next.next
curCopy = cur.next
cur.next = next
curCopy.next = next != null ? next.next : null
cur = next
}
return result
}
public static void printRandLinkedList(Node head) {
Node cur = head
System.out.print("order: ")
while (cur != null) {
System.out.print(cur.value + " ")
cur = cur.next
}
System.out.println()
cur = head
System.out.print("rand: ")
while (cur != null) {
System.out.print(cur.rand == null ? "- " : cur.rand.value + " ")
cur = cur.next
}
System.out.println()
}
public static void main(String[] args) {
Node head = null
Node res1 = null
Node res2 = null
printRandLinkedList(head)
res1 = copyListWithRand1(head)
printRandLinkedList(res1)
res2 = copyListWithRand2(head)
printRandLinkedList(res2)
printRandLinkedList(head)
System.out.println("=========================");
head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(5);
head.next.next.next.next.next = new Node(6);
head.rand = head.next.next.next.next.next; // 1 -> 6
head.next.rand = head.next.next.next.next.next; // 2 -> 6
head.next.next.rand = head.next.next.next.next; // 3 -> 5
head.next.next.next.rand = head.next.next; // 4 -> 3
head.next.next.next.next.rand = null; // 5 -> null
head.next.next.next.next.next.rand = head.next.next.next; // 6 -> 4
printRandLinkedList(head);
res1 = copyListWithRand1(head);
printRandLinkedList(res1);
res2 = copyListWithRand2(head);
printRandLinkedList(res2);
printRandLinkedList(head);
System.out.println("=========================");
}
}