3. 左右两侧链表,变成交叉链表
a -> b -> c -> 1 -> 2 -> 3 变成 a -> 1 -> b -> 2 -> c -> 3 结构,奇数中点变成最后一个
// 左右两侧链表,变成交叉链表
public void crossLink(Node head) {
if (head == null || head.next == null) {
return;
}
Node end = getMiddle(head, 0);
Node start = end.next;
// 变成两个链表织入问题
end.next = null;
Node next, startNext;
while (head != null) {
next = head.next;
head.next = start;
head = next;
if (start == null) {
return;
}
startNext = start.next;
start.next = head;
start = startNext;
}
}
public void crossLinkCompare(Node head) {
if (head == null) {
return;
}
List<Node> list = new ArrayList<>();
while (head != null) {
list.add(head);
head = head.next;
}
int N = list.size(), end = N / 2 - (N + 1) % 2, end0;
int i = 0;
for (; i < end; i++) {
end0 = end + i + 1;
list.get(i).next = list.get(end0);
list.get(end0).next = list.get(i + 1);
}
// 偶数,对尾节点进行单独考虑
if (N % 2 == 0) {
list.get(i).next = list.get(N - 1);
} else {
list.get(N - 1).next = list.get(i);
list.get(i).next = null;
}
}
@Test
public void test4() {
for (int i = 0; i < 1000; i++) {
Node node = Reduce.link(10, 100);
Node node1 = Reduce.copy(node);
Node node2 = Reduce.copy(node);
crossLink(node1);
crossLinkCompare(node2);
if (!CompareUtil.compare(node1, node2)) {
System.out.println(Printer.print(node));
System.out.println(Printer.print(node1));
System.out.println(Printer.print(node2));
return;
}
}
}
4. 给一个链表,和一个常数 V,使 < V 的在左侧,=V的在中间,> V 的在右侧
使用6个指针,分别是 小于,等于,大于 区的开始结束指针
// 给一个链表,和一个常数 V,使 < V 的在左侧,=V的在中间,> V 的在右侧
public Node partitionLink(Node node, int value) {
if (node == null) {
return null;
}
Node lessValueStart = null, lessValueEnd = null;
Node equalValueStart = null, equalValueEnd = null;
Node greaterValueStart = null, greaterValueEnd = null;
while (node != null) {
if (node.value < value) {
if (lessValueStart == null) {
lessValueStart = node;
lessValueEnd = node;
} else {
lessValueEnd.next = node;
lessValueEnd = node;
}
} else if (node.value == value) {
if (equalValueStart == null) {
equalValueStart = node;
equalValueEnd = node;
} else {
equalValueEnd.next = node;
equalValueEnd = node;
}
} else {
if (greaterValueStart == null) {
greaterValueStart = node;
greaterValueEnd = node;
} else {
greaterValueEnd.next = node;
greaterValueEnd = node;
}
}
node = node.next;
}
Node head1 = null, end = null;
if (lessValueStart != null) {
head1 = lessValueStart;
end = lessValueEnd;
}
if (equalValueStart != null) {
if (head1 != null) {
end.next = equalValueStart;
} else {
head1 = equalValueStart;
}
end = equalValueEnd;
}
if (greaterValueStart != null) {
if (head1 == null) {
head1 = greaterValueStart;
} else {
end.next = greaterValueStart;
}
end = greaterValueEnd;
}
end.next = null;
return head1;
}
public Node partitionLinkCompare(Node node, int value) {
if (node == null || node.next == null) {
return node;
}
List<Node> list = new ArrayList<>();
while (node != null) {
list.add(node);
node = node.next;
}
int less = 0, grater = list.size() - 1, i = 0;
while (i <= grater) {
int v = list.get(i).value;
if (v < value) {
swap(list, i++, less++);
} else if (v > value) {
swap(list, i, grater--);
} else {
swap(list, i++, less);
}
}
for (int j = 1; j < list.size(); j++) {
list.get(j - 1).next = list.get(j);
}
list.get(list.size() - 1).next = null;
return list.get(0);
}
private void swap(List<Node> list, int i, int j) {
Node temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
public boolean valid(Node node, int value) {
int i = 0, t;
while (node != null) {
t = node.value < value ? 1 : node.value == value ? 2 : 3;
if (i > t) {
return false;
}
i = t;
node = node.next;
}
return true;
}
@Test
public void test6() {
for (int i = 0; i < 10000; i++) {
Node node = Reduce.link(10, 100);
Node node1 = Reduce.copy(node);
Node node2 = Reduce.copy(node);
int value = Reduce.num(-100, 100);
Node n1 = partitionLink(node1, value);
Node n2 = partitionLinkCompare(node2, value);
if (!valid(n1, value) || !valid(n2, value)) {
System.out.println(value);
System.out.println(Printer.print(node));
System.out.println(Printer.print(n1));
System.out.println(Printer.print(n2));
return;
}
}
}
5. 复制一个链表,每一个节点有 next,random
// 基本思路是,先复制一个相同节点,连在 node后
public RandomNode copyRandomNode(RandomNode node) {
if (node == null) {
return null;
}
RandomNode curr1, curr = node;
RandomNode temp;
while (curr != null) {
curr1 = new RandomNode(curr.value);
temp = curr.next;
curr.next = curr1;
curr1.next = temp;
curr = temp;
}
RandomNode res = node.next;
curr = node;
while (curr != null) {
curr.next.random = curr.random == null ? null : curr.random.next;
curr.next = curr.next.next;
curr = curr.next;
}
return res;
}
public RandomNode copyRandomNodeCompare(RandomNode node) {
Map<RandomNode, RandomNode> map = new HashMap<>();
RandomNode curr = node;
while (curr != null) {
map.put(curr, new RandomNode(curr.value));
curr = curr.next;
}
curr = node;
while (curr != null) {
map.get(curr).next = map.get(curr.next);
map.get(curr).random = curr.random == null ? null : map.get(curr.random);
curr = curr.next;
}
return map.get(node);
}
@Test
public void test7() {
for (int i = 0; i < 1000; i++) {
RandomNode node = Reduce.randomNode(5, 100);
RandomNode node1 = copyRandomNode(node);
RandomNode node2 = copyRandomNodeCompare(node);
if (!CompareUtil.compare(node1, node2)) {
System.out.println(Printer.print(node));
System.out.println(Printer.print(node1));
System.out.println(Printer.print(node2));
return;
}
}
}