逆リンクリスト(シンプル)
非常に便利な単純な反転リンクリストから始めましょう。他のリンクリストの質問では、リンクリストを反転する手順を使用します。
タイトル説明
単一リンクリストを逆にします。
例:
入力: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)空間計算量でこの問題を解決できますか?
アイデア
リンクリストの前半と後半のノード値が反転後、1つずつ同じであるかどうかを判断するだけで済みます。
前半と後半を見つける方法は?
高速および低速ポインタメソッドは、リンクリストの質問で非常に役立ちます。覚えておいてください。たとえば、リンクリストの下部からどのノードを見つけることができます。これは、ノードの下半分を見つけることと同じです。
- 最初に前半と後半を見つけます
- 後半を逆にします(前の質問の再帰的な方法)
- 前半分と後ろ半分のノード値を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;
}
}