1. 求链表的中点
1)输入链表头节点,奇数长度返回中点,偶数长度返回上中点
2)输入链表头节点,奇数长度返回中点,偶数长度返回下中点
3)输入链表头节点。奇数长度返回中点前一个,偶数长度返回上中点前一个
4)输入链表头节点,奇数长度返回中点前一个,偶数长度返回下中点后一个
快慢指针
/**
* 1)输入链表头节点,奇数长度返回中点,偶数长度返回上中点
* 2)输入链表头节点,奇数长度返回中点,偶数长度返回下中点
* 3)输入链表头节点。奇数长度返回中点前一个,偶数长度返回上中点前一个
* 4)输入链表头节点,奇数长度返回中点后一个,偶数长度返回下中点后一个
* 0 上中点
* 1 下中点
* 2 上中点前一个
* 3 下中点后一个
*
* @param head 头节点
* @param mode 模式
* @return 中点
*/
public Node getMiddle(Node head, int mode) {
if (head == null || head.next == null) {
return head;
}
if ((mode == 2 || mode == 3) && head.next.next == null) {
return null;
}
Node ppre = null;
Node pre = null;
Node s = head;
Node f = head;
while (f != null) {
// 奇数长度
if (f.next == null) {
return mode == 0 || mode == 1 ? s : mode == 3 ? s.next : pre;
}
if (pre != null) {
ppre = pre;
}
pre = s;
s = s.next;
f = f.next.next;
}
return mode == 0 ? pre : mode == 1 ? s : mode == 3 ? s.next : ppre;
}
public Node getMiddleCompare(Node node, int mode) {
if (node == null || node.next == null) {
return node;
}
if ((mode == 2 || mode == 3) && node.next.next == null) {
return null;
}
List<Node> nodes = new ArrayList<>();
while (node != null) {
nodes.add(node);
node = node.next;
}
int N = nodes.size();
int middle = N / 2;
// 是否是奇数
int uneven = (N + 1) % 2;
if (mode == 0) {
return nodes.get(middle - uneven);
} else if (mode == 1) {
return nodes.get(middle);
} else if (mode == 2) {
return nodes.get(middle - uneven - 1);
} else {
return nodes.get(middle + 1);
}
}
2. 给定一个单链表的头节点head,请判断该链表是否为回文结构。
- 使用栈实现
- 找到中点,左侧的链表逆序,左右链表进行比较,返回前右侧逆序
// 逆序
public Node reverse(Node head, Node end) {
Node pre = null, curr = head, next;
while (curr != end) {
next = curr.next;
curr.next = pre;
pre = curr;
curr = next;
}
if (end != null) {
end.next = pre;
}
return end == null ? pre : end;
}
public boolean isPalindrome(Node node) {
if (node == null) {
return false;
}
if (node.next == null) {
return true;
}
Node middle = getMiddle(node, 1);
// 从中点到结尾逆序
Node end = reverse(middle, null);
if (end == middle) {
return end.value == node.value;
}
// 比较
Node end1 = end;
while (end1 != middle) {
if (end1.value != node.value) {
reverse(end, middle);
return false;
}
end1 = end1.next;
node = node.next;
}
reverse(end, middle);
return middle.value == node.value;
}
public boolean isPalindromeCompare(Node node) {
if (node == null) {
return false;
}
Stack<Node> stack = new Stack<>();
Node curr = node;
while (curr != null) {
stack.push(curr);
curr = curr.next;
}
curr = node;
while (curr != null) {
node = stack.pop();
if (node.value != curr.value) {
return false;
}
curr = curr.next;
}
return true;
}