反轉鏈表(簡單的)
先來個簡單的反轉鏈表,用處大大地,後面的其他鏈表題會用到反轉鏈表這個步驟哦
題目描述
反轉一個單鏈表。
示例:
輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL
思路
遞歸法
- 遞歸的終止是:當前節點爲空 或者 它的指向爲空
- 反轉當前節點,先反轉下一個節點;
- 下一個節點指向當前節點;
- 當前節點指向空;
Java代碼
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
//遞歸法
if(head == null || head.next == null) return head;
//新的頭節點
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
}
迴文鏈表
看,用處來了吧
題目描述
請判斷一個鏈表是否爲迴文鏈表。
示例 1:
輸入: 1->2
輸出: false
示例 2:
輸入: 1->2->2->1
輸出: true
進階:
你能否用 O(n) 時間複雜度和 O(1) 空間複雜度解決此題?
思路
只需要判斷一個鏈表的前半段和後半段反轉後的節點值是否一一相同就行了。
怎麼找出前半段,後半段呢?
快慢指針法這個方法在鏈表題中很有用,要記住。比如,它可以找出鏈表的倒數第幾個節點。這裏相當於是找到倒數一半的節點。
- 先找出前、後半段
- 反轉後半段(上題的遞歸法)
- 一一對比前後半段的節點值
Java代碼
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
//遞歸反轉一個鏈表
public ListNode reverse(ListNode head){
if(head.next == null) return head;
ListNode newHead = reverse(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
public boolean isPalindrome(ListNode head) {
//特殊情況
if(head ==null || head.next == null) return true;
//快慢指針,尋找中點
ListNode fast = head;
ListNode slow = head;
while(fast.next!=null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
//翻轉後半段
slow = reverse(slow.next);
//對比
while(slow!=null){
if(head.val!=slow.val) return false;
head = head.next;
slow = slow.next;
}
return true;
}
}