剑指 Offer II 027. 回文链表
一、反转链表
Java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
StringBuilder stringBuilder=new StringBuilder();
StringBuilder reverse=new StringBuilder();
while(head!=null){
stringBuilder.append(head.val);
reverse.append(head.val);
head=head.next;
}
reverse.reverse();
return stringBuilder.toString().equals(reverse.toString());
}
}
二、快慢指针
找到前半部分链表的尾节点。
反转后半部分链表。
判断是否回文。
恢复链表。
返回结果。
此方法时间复杂度:O(N);空间复杂度:O(1)
Java
class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null) {
return true;
}
ListNode firstHalfEnd = endOfFirstHalf(head);
ListNode secondHalfStart = reverseList(firstHalfEnd.next);
ListNode p1 = head;
ListNode p2 = secondHalfStart;
boolean result = true;
while (result && p2 != null) {
if (p1.val != p2.val) {
result = false;
}
p1 = p1.next;
p2 = p2.next;
}
firstHalfEnd.next = reverseList(secondHalfStart);
return result;
}
private ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
private ListNode endOfFirstHalf(ListNode head) {
ListNode p = head;
ListNode q = head;
while (p.next != null && p.next.next != null) {
p = p.next.next;
q = q.next;
}
return q;
}
}
C++
class Solution {
public:
bool isPalindrome(ListNode* head) {
if (head == nullptr) {
return true;
}
ListNode* firstHalfEnd = endOfFirstHalf(head);
ListNode* secondHalfStart = reverseList(firstHalfEnd->next);
ListNode* p1 = head;
ListNode* p2 = secondHalfStart;
bool result = true;
while (result && p2 != nullptr) {
if (p1->val != p2->val) {
result = false;
}
p1 = p1->next;
p2 = p2->next;
}
firstHalfEnd->next = reverseList(secondHalfStart);
return result;
}
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr != nullptr) {
ListNode* nextTemp = curr->next;
curr->next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
ListNode* endOfFirstHalf(ListNode* head) {
ListNode* p = head;
ListNode* q = head;
while (p->next != nullptr && p->next->next != nullptr) {
p = p->next->next;
q = q->next;
}
return q;
}
};
Python
class Solution:
def isPalindrome(self, head: ListNode) -> bool:
if head is None:
return True
first_half_end = self.end_of_first_half(head)
second_half_start = self.reverse_list(first_half_end.next)
result = True
first_position = head
second_position = second_half_start
while result and second_position is not None:
if first_position.val != second_position.val:
result = False
first_position = first_position.next
second_position = second_position.next
first_half_end.next = self.reverse_list(second_half_start)
return result
def end_of_first_half(self, head):
p = head
q = head
while p.next is not None and p.next.next is not None:
p = p.next.next
q = q.next
return q
def reverse_list(self, head):
previous = None
current = head
while current is not None:
next_node = current.next
current.next = previous
previous = current
current = next_node
return previous
剑指 Offer II 028. 展平多级双向链表
DFS代码
/*
// Definition for a Node.
class Node {
public int val;
public Node prev;
public Node next;
public Node child;
};
*/
class Solution {
public Node flatten(Node head) {
dfs(head);
return head;
}
public Node dfs(Node node) {
Node cur = node;
Node last = null;
while (cur != null) {
Node next = cur.next;
if (cur.child != null) {
Node childLast = dfs(cur.child);
next = cur.next;
cur.next = cur.child;
cur.child.prev = cur;
if (next != null) {
childLast.next = next;
next.prev = childLast;
}
cur.child = null;
last = childLast;
} else {
last = cur;
}
cur = next;
}
return last;
}
}
时间复杂度:O(n),其中n 是链表中的节点个数。
空间复杂度:O(n)
剑指 Offer II 029. 排序的循环链表
首先,循环单链表往往将操作指针p指向尾部(即本题中的最后一个最大值);接着,如果值大于等于最大值或者小于等于最小值,那么往p的后面插入就可以了反之就去查找插入位置,最后插入就可以了。
代码
/*
// Definition for a Node.
class Node {
public int val;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _next) {
val = _val;
next = _next;
}
};
*/
class Solution {
public Node insert(Node head, int insertVal) {
if(head == null) {
Node res = new Node(insertVal);
res.next = res;
return res;
}
if(head.next == head) {
head.next = new Node(insertVal, head);
return head;
}
Node p = head;
do{
if(p.next.val >= p.val) {
if(insertVal >= p.val && insertVal <= p.next.val) {
p.next = new Node(insertVal, p.next);
return head;
}
}
else {
if(insertVal >= p.val || insertVal <= p.next.val) {
p.next = new Node(insertVal, p.next);
return head;
}
}
p = p.next;
}
while(p != head);
head.next = new Node(insertVal, head.next);
return head;
}
}
时间复杂度:O(N)
空间复杂度:O(1)