タイトル
nは位置Mからの逆リスト。完全な逆転でスキャンへの旅行をご使用ください。
説明:
1≤≤M≤N-長のリスト。
例:
入力:1-> 2-> 3-> 4- > 5-> NULL、M = 2、N = 4
出力:1-> 4-> 3-> 2- > 5-> NULL
出典:滞在ボタン(LeetCode)
リンク:リンク
問題解決のためのアイデア
まず、のは、対象を分析してみましょう、この質問は、リンクリストを逆に似ていますが、私はそれが問題解決のアイデアの難しさだと思うので、範囲の反転を設定します:
- 逆転のリスト
- 特殊な状況(例えば、M = 1)
- 接続のリスト
まず、聞かせてのは、ここで最初の質問は、反転、参照記事の単一のリストを必要とする分析:リンク
自身が次のように要約します:
- 第一の方法:
開始を設定し、ヘッドノードがNULLに初期化し、ヘッドにオリジナルおよび新規リストのリンクされたリストの先頭から取られたノードが挿入され、次のように、特定のコードです。
ListNode* change(ListNode* head){
ListNode* start = NULL;
ListNode* p=head; //p指针为工作节点
ListNode* temp;//保存下一个节点
while(p!=NULL)
{
tmp = p -> next;
p -> next = newh;//将节点插入到头节点
newh = p;//然后设置新的头节点为新插入的节点
p = tmp;//重新设置工作节点p
}
return newh;
}
- 第二の方法:
毎回新しいヘッダ内の後の最初のノードの後に元のノード
ListNode* ReverseList(ListNode* head) {
if(head == NULL)
return head;
ListNode *res,*first,*temp;
res = new ListNode(-1);//设置新的头节点
res->next = head;
first = res->next; //first 始终为第一个结点,不断后移,res为新表头
while(first->next!=NULL)
{
temp = first->next;
first->next = temp->next;
//将头节点放在新表头的后面
temp->next = res->next;
res->next = temp;
}
return res->next;
}
第二の困難のために、特別な場合を扱います。
- M == nは、それはリストを反転させることが証明されていない、直接のリターン
- m = 1で、問題が存在することになる場合に:我々は、最初のノードをスキップする(なぜならノード=ノード - >次)我々は、ダミーノードを設定するので、(このアイデアは、リスト分割に由来する)、次に設定ヘッドノードにダミーノードの横
主にリストの接続について:リストと接続リストの先頭が反転し、反転リストとリンクリストの背中を非反転
次のようにそのため、全体の特定のコードです。
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
if (m == n) //如果两者相等,直接返回头节点
return head;
if (head == NULL)
return NULL;
int i = 1;
ListNode emp(0); //设置哑节点
emp.next = head;
ListNode* node = &emp;
ListNode* Head=NULL;//反转链表的头节点
ListNode* first,*end;
ListNode* temp=NULL;
while (i < m ) {
node = node->next;
i++;
}
first=end = node->next; //假设不设置哑节点,则会直接跳过头节点
i = 0;
//进行链表的反转,用的是第一种方法
while (i <= n - m) {
temp = first->next;
first->next = Head;
Head = first;
first = temp;
i++;
}
end->next = temp; //这里连接的是反转链表和后面未反转链表的连接
node->next = Head;
return emp.next;
}
};