単一リンクリストのヘッドノードヘッドを指定して、すべてのKノードが逆の順序でグループ化されるように単一リンクリストを調整する関数を実装します。リンクリストの末尾から開始して、ヘッドの残りのノードは次のようになります。 1つのグループには不十分です。順序を逆にする必要があります。(キューまたはスタックを補助として使用することはできません)
例:
リンクリスト:1-> 2-> 3-> 4-> 5-> 6-> 7-> 8-> null、K = 3。次に、各グループについて6-> 7-> 8、3-> 4-> 5、1-> 2。調整後:1-> 2-> 5-> 4-> 3-> 8-> 7-> 6-> null。なかでも1、2は足りないので調整していません。
この質問の難しさは、リンクリストの先頭からではなく、リンクリストの末尾から始まることです。先頭の場合は、リンクリストをトラバースできるため、簡単に実行できます。 kをトラバースするたびにグループに分割して順序を逆にします。ただし、これは単一リンクリストであり、グループを逆方向にトラバースできないため、最後とは異なります。しかし、この質問は再帰を使用する方が間違いなく優れています。この記事では、再帰に関するいくつかのルーチンについて説明しました。
最初に同様の逆転問題を実行します
この問題を実行する前に、頭から始めた場合に何をすべきかを見てみましょう。例:リンクリスト:1-> 2-> 3-> 4-> 5-> 6-> 7-> 8-> null、K = 3。調整後:3-> 2-> 1-> 6-> 5-> 4-> 7-> 8-> null。なかでも7と8は足りないので調整していません。
再帰を使用してこの問題を実装できます。reverseKNode()メソッドの関数が(先頭からグループ化された)単一リンクリストの各Kノードの順序を逆にすることであると仮定すると、reverse()メソッドの関数は次のようになります。単一のリンクリストは逆の順序です。
次に、以下の単一リンクリストの場合、K = 3です。
最初のK個のノードを次のノードから分割します
。tempが指す残りのリンクリストは、元の問題のサブ問題であると言えます。
reverseKNode()メソッドを呼び出して、tempが指すリンクリスト内のKノードの順序を逆にすることができます。
次に、reverse()メソッドを呼び出して、headが指す3つのノードの順序を逆にします。結果は、次のようになります。
次に、2つの部分を接続するだけです。最終結果は次のとおりです。
//k个为一组逆序
public ListNode reverseKGroup(ListNode head, int k) {
ListNode temp = head;
for (int i = 1; i < k && temp != null; i++) {
temp = temp.next;
}
//判断节点的数量是否能够凑成一组
if(temp == null)
return head;
ListNode t2 = temp.next;
temp.next = null;
//把当前的组进行逆序
ListNode newHead = reverseList(head);
//把之后的节点进行分组逆序
ListNode newTemp = reverseKGroup(t2, k);
// 把两部分连接起来
head.next = newTemp;
return newHead;
}
//逆序单链表
private static ListNode reverseList(ListNode head) {
if(head == null || head.next == null)
return head;
ListNode result = reverseList(head.next);
head.next.next = head;
head.next = null;
return result;
}
この質問に戻る
これらの2つの質問は、1つが頭から始まることを除いて、非常に似ていると言えます。これは頭から始まり、Leetcodeの25番目の質問でもあります。インタビューでは、歪みが生じることがよくあります。たとえば、このバイトジャンプの質問は最後からグループ化されています。しばらくの間、その方法がわからない場合があります。もちろん、誰かがすぐに反応して数秒で彼を殺すかもしれません。
実際、この質問は非常に簡単です。単一リンクリストを1回逆にするだけで済みます。逆の順序の後、先頭からグループに変換し、上記の解決策に従うことができます。処理後、もう一度結果を出します。2つの逆順は、逆順がないことと同じです。
たとえば、リンクリスト(K = 3の場合)の場合
テールからグループ化し、Kノードごとにグループとして順序を逆にします。
次のように実行します。
1.最初に逆順を実行します。逆順の後、
問題は先頭から始まるグループに変換でき、各Kノードは逆順のグループになります。
2.処理結果は以下のとおりです
。3。次に、結果を1回反転すると、
次のようになります。
public ListNode solve(ListNode head, int k) {
// 调用逆序函数
head = reverse(head);
// 调用每 k 个为一组的逆序函数(从头部开始组起)
head = reverseKGroup(head, k);
// 在逆序一次
head = reverse(head);
return head;
}
最初に逆にする必要があるこの種の質問と同様に、2つのリンクリストを追加する必要があります。この質問には、バイトビートを使用した筆記試験があります。次の図の2番目の質問:この
質問は、リンクされた2つの順序を逆にする必要があります。最初にリストを作成し、次にノードを追加して最後にマージします。
まとめ
リンクリストのアルゴリズムの質問については、インタビュー中によくテストされていると聞きましたので、もっと注意を払ってください。
パブリックアカウントから転載:アルゴリズムを学ぶために5分