説明
単一リンク リストのヘッド ノード pHead (ヘッド ノードには値があります。たとえば、下の図では val は 1) を指定すると、長さは n になり、リンク リストを反転した後、新しいリンクのヘッドを返します。リスト。
データ範囲: 0≤n≤1000
要件: 空間計算量 O(1)、時間計算量 O(n)。
たとえば、リンク リスト {1,2,3} を入力すると、
反転後、元のリンク リストは {3,2,1} になるため、対応する出力は {3,2,1} になります。
上記の変換プロセスを次の図に示します。
例1
入力:
{1,2,3}
戻り値をコピーします:
{3,2,1}
コピー
例 2
入力:
{}
戻り値をコピーします:
{}
コピー手順:
空のリンク リストは空を出力します
解決策 1 (c)
初期化: 3 ポインタ
1) pre ポインタは、反転されたリンク リストの最後のノードを指します。先頭には反転がないため、NULL を指します。 2) cur ポインタは、リンク リストの最初のノードを指します
。反転するリスト、先頭の最初のノード ノードは反転するので、head を指します。
3) next ポインタは、反転するリンク リストの 2 番目のノードを指します。目的は、リンク リストを保存することです。 cur がポインタを変更すると、後続のリンク リストが無効になるため、保存する必要があります。 次に、以下をループで実行します。 3 つの操作 1) nex = cur->
next
、save 関数
2) cur->next = pre非反転リンク リストの最初のノードの次のポインタは、反転リンク リストの最後のノードを指します
3) pre = cur, cur = nex; ポインタを後方に移動し、次の非反転リンク リストの最初のノードを操作します
。 、もちろん、 cur != NULL です。
ループが終了すると、cur は当然 NULL になるため、反転したヘッダー ポイントである pre を返します。
コード:
struct ListNode* ReverseList(struct ListNode* pHead ) {
// write code here
if (pHead==NULL) return NULL;
struct ListNode *pre=NULL;
struct ListNode *cur=pHead;
struct ListNode *nex=NULL;
while(cur){
nex=cur->next;
cur->next=pre; //未反转链表的第一个节点的下个指针指向已反转链表的最后一个节点
pre=cur;
cur=nex;
}
return pre;
}
解決策 2 (C++)
リンクされたリストを構築し、最初にベクトルを使用して保存してから構築します
時間計算量: O(n)
空間計算量: O(n)、単一のリンク リストを格納するためにベクトルが使用されます。
コード:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(!pHead) return nullptr;
vector<ListNode*> v;
while(pHead){
v.push_back(pHead);
pHead=pHead->next;
}
reverse(v.begin(), v.end()); //反转vector 或者逆向遍历
ListNode *head=v[0];
ListNode *cur=head;
for(int i=1;i<v.size();i++){ //构造链表
cur->next=v[i]; //当前节点的下一个指针指向下一个节点
cur=cur->next; //当前指针后移
}
cur->next=nullptr; //切记最后一个节点的下一个指针指向nullptr
return head;
}
};
解決策 3 (Java)
スタックを使用すると、スタックは先入れ後出になります。
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
import java.util.Stack;
public class Solution {
public ListNode ReverseList(ListNode head) {
Stack<ListNode> stack =new Stack<>();
//把链表节点全部摘掉放到栈中
while(head!=null){
stack.push(head);
head=head.next;
}
if(stack.isEmpty()) return null;
ListNode node=stack.pop();
ListNode dummy =node;
//栈中的结点全部出栈,然后重新连成一个新的链表
while(!stack.isEmpty()){
ListNode tempnode=stack.pop();
node.next=tempnode;
node=node.next;
}
//最后一个结点就是反转前的头结点,一定要让他的next
//等于空,否则会构成环
node.next=null;
return dummy;
}
}