【LeetCode】 Reverse Linked List 翻转链表 ( Uber,FB )

来源:互联网 发布:网络电话卡app制作 编辑:程序博客网 时间:2024/06/05 06:24

Reverse Linked List I(Easy)
翻转链表

样例
给出一个链表1->2->3->null,这个翻转后的链表为3->2->1->null

挑战
在原地一次翻转完成

标签
链表 优步 脸书

Java:

/** * Definition for ListNode. * public class ListNode { *     int val; *     ListNode next; *     ListNode(int val) { *         this.val = val; *         this.next = null; *     } * } */ public class Solution {    /**     * @param head: The head of linked list.     * @return: The new head of reversed linked list.     */    public ListNode reverse(ListNode head) {        ListNode prev = null;        while(head != null){        ListNode temp = head.next;//向前翻转        head.next = prev;        prev = head;//指针后移        head = temp;        }        return prev;    }}

Reverse Linked List II (Medium)

Reverse a linked list from position m to n.

Notice
Given m, n satisfy the following condition: 1 ≤ m ≤ n ≤ length of list.

Example
Given 1->2->3->4->5->NULL, m = 2 and n = 4, return 1->4->3->2->5->NULL.

Challenge
Reverse it in-place and in one-pass

Tags
Linked List
Related Problems
Hard Reverse Nodes in k-Group 35 %
Easy Reverse Words in a String 25 %
Easy Reverse Linked List 41 %

(1)C++

#include "stdafx.h"#include <iostream>#include <cstdio>using namespace std;typedef struct tagSNode{    int value;    tagSNode* pNext;    tagSNode(int v) :value(v), pNext(NULL) {}}SNode;void Reverse(SNode* pHead, int from, int to) {    if (from >= to || pHead == NULL) {        return;    }    SNode* pCur = pHead->pNext;    int i;    for (i = 0; i < from - 1; i++) {//空转from-1次,找到起始结点        if (pHead == NULL)            return;        pHead = pCur;        pCur = pCur->pNext;    }    SNode* pPre = pCur;//pPre是from的前驱结点    pCur = pCur->pNext;    SNode*pNext;    for (; i < to - 1; i++) {//此前i == from - 1, 循环中:i从from - 1,到to - 1        pNext = pCur->pNext;        pCur->pNext = pHead->pNext;        pHead->pNext = pCur;        pPre->pNext = pNext;        pCur = pNext;    }}void Print(SNode* sn) {    SNode* p = sn->pNext;    while (p)    {        if (p->pNext != NULL) {            cout << p->value << " -> ";        }        else {            cout << p->value;        }        p = p->pNext;    }    cout << endl;}void Destroy(SNode* p) {    SNode* next;    while (p) {        next = p->pNext;        delete p;        p = next;    }}int main(){    SNode* pHead = new SNode(0);    int i;    for (i = 0; i < 10; i++)    {        SNode* p = new SNode(rand() % 10);        p->pNext = pHead->pNext;        pHead->pNext = p;    }    Print(pHead);    Reverse(pHead, 4, 8);    Print(pHead);    Destroy(pHead);    return 0;}

(2) ①Java:

1)Java√/** * Definition for ListNode * public class ListNode { *     int val; *     ListNode next; * } */public class Solution {    public ListNode reverseBetween(ListNode head, int m, int n) {        if (m >= n || head == null) {            return head;        }        ListNode dummy = new ListNode(0);        dummy.next = head;        head = dummy;        for (int i = 1; i < m; i++) { //空转from-1次,找到起始结点(效果:指针后移到pPre)            if (head == null) {                return null;            }            head = head.next;        }        ListNode premNode = head; //pPre是from的前驱结点        ListNode mNode = head.next;        ListNode nNode = mNode, postnNode = mNode.next;        for (int i = m; i < n; i++) {            if (postnNode == null) {                return nu3ll;            }            ListNode temp = postnNode.next; //向前翻转            postnNode.next = nNode;            nNode = postnNode;           postnNode = temp;//后移指针        }        mNode.next = postnNode;//(翻转部分)尾部相接: 最后一次翻转结束后,postnNode在末端结点的后面(最后结点的下一个pNext),mNode为翻转的链表的最后一个结点。二者需要相连。        premNode.next = nNode;//(翻转部分)头部相接:premNode在头部(翻转前from的前驱结点,即反转部分的前一个个结点),nNode一直作为翻转部分的头结点。二者需要相连。        return dummy.next;    }}②//Version 2public class ReverseBetween {    public ListNode reverseBetween(ListNode head, int m, int n) {        if (head == null || head.next == null) {            return head;        }        if (m >= n) {            return head;        }        ListNode dummy = new ListNode(0);        dummy.next = head;        ListNode pre = dummy;        //1. get the pre node before m.        for (int i = m; i > 1; i--) {            pre = pre.next;        }        // record the tail of the reversed link.        ListNode reverseTail = pre.next;        pre.next = null;        // reverse the link.        ListNode cur = reverseTail;        for (int i = n - m + 1; i > 0; i--) {            if (i == 1) {                // 这里是翻转段后的第一个元素 .                reverseTail.next = cur.next;            }            ListNode tmp = cur.next;            cur.next = pre.next;            pre.next = cur;            cur = tmp;        }        return dummy.next;    }}

②C++

class Solution {    public:    void reverse(ListNode *head) {        ListNode *prev = NULL;        while (head != NULL) {            ListNode *temp = head->next;//将后面的结点向前翻转            head->next = prev;            prev = head;//指针后移            head = temp;        }    }    ListNode *findkth(ListNode *head, int k) {//空转k-1次,找到起始结点        for (int i = 0; i < k; i++) {            if (head == NULL) {                return NULL;            }            head = head->next;        }        return head;    }    ListNode *reverseBetween(ListNode *head, int m, int n) {        ListNode *dummy = new ListNode(-1, head);        ListNode *mth_prev = findkth(dummy, m - 1);        ListNode *mth = mth_prev->next;        ListNode *nth = findkth(dummy, n);        ListNode *nth_next = nth->next;        nth->next = NULL;        reverse(mth);        mth_prev->next = nth;//尾部相接        mth->next = nth_next;        return dummy->next;    }};