思路
通过快慢指针定位到中间节点,通过将前半段反序,然后与后半段比较。
重点
- 快慢指针
慢指(s)针一次走一格,快指针(f)一次走2格,当f 存在子节点与孙子节点时循环执行。
例如:1 2 3 3 2 1
起始时 s 与 f 均指向1
第一次循环结束 s 指向 2,f 指向 3
第二次循环结束 s 指向 3,f 指向 2
f 有子节点没有孙子节点,退出循环
这时,如果字符串长度是单数则s 节点就是中间节点;如果偶数则s 节点与s 节点的子节点都是中间节点。 - 反链
具体见代码注释
代码
Node节点
package com.jiaotd.lru.sorted_single_lineked;
public class Node<T> {
private T i;
private Node next;
public Node(T i) {
this.i = i;
}
public boolean hasNext() {
return null != next;
}
public Node add(Node node) {
node.setNext(this);
return node;
}
public T getI() {
return i;
}
public void setI(T i) {
this.i = i;
}
public Node<T> getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public static void print(Node node) {
Node<String> temp = node;
while (null != temp) {
System.out.println(temp.getI());
temp = temp.getNext();
}
System.out.println("=====================");
}
}
逻辑代码
package com.jiaotd.lru.sorted_single_lineked;
public class ReturnString {
/**
* fast slow
*
* @param node
*/
public void judge(Node<String> node) {
Node<String> head = node;
Node<String> fast = node;
Node<String> slow = node;
while (null != fast.getNext() && null != fast.getNext().getNext()) {
slow = slow.getNext();
fast = fast.getNext().getNext();
}
if (null == fast.getNext()) {
// 奇数长度,slow就是中间节点
Node<String> conver = convert(head, slow);
// 12321 conver后 321 中间不要21,右边21
System.out.println(isReturn(conver.getNext(), slow.getNext()));
} else {
// 偶数长度,slow 与 slow.getNext 都是中间节点
Node<String> conver = convert(head, slow);
System.out.println(isReturn(conver, slow.getNext()));
}
}
public boolean isReturn(Node<String> left, Node<String> right) {
while (null != left && null != right) {
if (!left.getI().equals(right.getI())) {
return false;
}
left = left.getNext();
right = right.getNext();
}
return true;
}
public Node<String> convert2(Node<String> head, Node<String> middle) {
Node<String> conver = new Node<String>(head.getI());
Node<String> pos = head;
while (pos != middle) {
pos = pos.getNext();
Node<String> temp = new Node<String>(pos.getI());
temp.setNext(conver);
conver = temp;
}
Node.print(conver);
return conver;
}
/**
* conver 反转的链
*
* 1.next 记录以后节点的起点
* 2.pos 连接反转的 conver链
* 3.将新生成的反链指向conver
* 4.pos 指向 下次执行的起点next
*
* 1->2->5->3->1->null
*
* conver:null
* pos:1->2->5->3->1->null
*
* 第一次执行:
* next:2->5->3->1->null //记录下次起点
* pos:1->null //开始反转
* conver:1->null //反转后指向cover
* pos:2->5->3->1->null //pos指向下次执行的起点
*
* 第二次执行:
* next:5->3->1->null //记录下次起点
* pos:2->1->null //开始反转
* conver:2->1->null //反转后指向cover
* pos:5->3->1->null //pos指向下次执行的起点
* @param head
* @param middle
* @return
*/
public Node<String> convert(Node<String> head, Node<String> middle) {
Node<String> conver = null;
Node<String> pos = head;
while (pos != middle) {
Node<String> next = pos.getNext();
pos.setNext(conver);
conver = pos;
pos = next;
}
pos.setNext(conver);
Node.print(pos);
return pos;
}
public static void main(String[] args) {
ReturnString rs = new ReturnString();
String str = "12521";
Node<String> head = new Node<String>(String.valueOf(str.charAt(0)));
Node<String> pos = head;
for (int i = 1; i < str.length(); i++) {
char c = str.charAt(i);
Node<String> node = new Node<String>(String.valueOf(c));
pos.setNext(node);
pos = node;
}
Node.print(head);
rs.judge(head);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。