单链表结构
public class Node<V> {
V value;
Node next;
}
双链表
public class DoubleNode<V> {
V value;
DoubleNode next;
DoubleNode last;
}
反转单向链表
public static Node reverseList(Node curNode) {
Node pre = null;
Node next = null;
while (curNode != null) {
next = curNode.next; // 获取下一个node
curNode.next = pre; //将当前node的下一个指向前一个
pre = curNode; //更新 前一个Node
curNode = next; // 更新 当前Node
}
return pre;
}
反转双向链表
public static DoubleNode reverseNode(DoubleNode head) {
DoubleNode curNode = head;
DoubleNode pre = null;
DoubleNode next = null;
while (curNode.next != null) {
next = curNode.next;
curNode.next = pre;
curNode.pre = next;
pre = curNode;
curNode = next;
}
return pre;
}
打印俩个 有序链表 的公共部分
俩个指针,谁小谁移动,相等打印,然后都移动。 一个到头停止
public static void printCommonPart(Node node1, Node node2) {
while (node1 != null && node2 != null) {
if (node1.value < node2.value) {
// 谁小谁移动
node1 = node1.next;
} else if (node1.value > node2.value) {
node2 = node2.next;
} else {
// 一样打印
System.out.print(node1.value + " ");
// 都移动
node1 = node1.next;
node2 = node2.next;
}
}
}
判断一个链表是否为回文结构
对称轴是虚的, 或者不是虚的
- 使用栈,全部 先入栈,然后比较
- 只放右边的数据。省一半空间,快慢指针,快指针走俩步,慢指针走一步,快指针走到结尾,慢指针就到中间的部分 了
考虑奇数 偶数
public static boolean ispalindromeList_01(Node head) {
// 判断一个链表是否为回文结构。使用栈,简单,空间复杂度较高
Stack<Node> stack = new Stack<>();
// 入栈
Node curNode = head;
while (curNode != null) {
stack.push(curNode);
curNode = curNode.next;
}
// 出栈比较
while (head != null) {
Node stackNode = stack.pop();
if (stackNode.value != head.value) {
return false;
}
head = head.next;
}
return true;
}
只添加右半部分,使用快慢指针
public static boolean ispalindromeList_02(Node head) {
// 判断一个链表是否为回文结构。使用栈,简单,空间复杂度较高
Stack<Node> stack = new Stack<>();
Node f = head; // 快指针
Node s = head; // 慢指针
while (f != null) {
f = f.next;
if (f != null) {
f = f.next;
} else {
break;
}
s = s.next;
}
System.out.println("===s-> " + s.value);
while (s != null) {
stack.push(s);
s = s.next;
}
while (!stack.empty()) {
Node stackNode = stack.pop();
if (head.value != stackNode.value) {
return false;
}
head = head.next;
}
return true;
}
快慢指针判断优化:
注意:判断是否为空,使用快指针。
while (f.next != null && f.next.next != null) {
s = s.next;
f = f.next.next;
}
- 如果要求 空间复杂度为O(1)
通过修改链表,也是快慢指针,但是不用栈了,当慢指针到了中间位置,后续的node 逆序,然后 向中间走,依次比较。
public static boolean ispalindromeList_03(Node head) {
if (head == null || head.next == null) {
return true;
}
Node s = head;
Node f = head;
while (f.next != null && f.next.next != null) {
s = s.next;
f = f.next.next;
}
// 右边第一个node
Node right_first_node = s.next;
// Node right_node = right_first_node;
// 将中间的下一个 next置为null
s.next = null;
// 将右边的逆序
Node right_pre = null;
Node right_next = null;
while (right_first_node != null) {
right_next = right_first_node.next; // 获取下一个node
right_first_node.next = right_pre; // 当前node 的下一个指向前一个node
right_pre = right_first_node; // 更新 pre
right_first_node = right_next; // 更新 当前node 为下一个
}
// 保存右边 最后一个node,就是right_pre,
Node right_last_node = right_pre;
// 左边第一个 node
Node left_first_node = head;
boolean res = true;
// 循环结束条件,下一个元素为空
while (left_first_node != null && right_last_node != null) {
if (left_first_node.value != right_last_node.value) {
// 如果出现不等,就退出
res = false;
break;
}
// 更新左右 node 为下一个
left_first_node = left_first_node.next;
right_last_node = right_last_node.next;
}
// 恢复 链表,
// 中间node 指向右边第一个,
right_first_node = s.next;
// 继续逆序
// 将右边的逆序
Node right_recover_pre = null;
Node right_recover_next = null;
while (right_last_node != null) {
right_recover_next = right_last_node.next;
right_last_node.next = right_recover_pre;
right_recover_pre = right_last_node;
right_last_node = right_recover_next;
}
return res;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。