[LeetCode] Reverse Linked List I II - 链表翻转问题

简介:

题目概述:
        Reverse a singly linked list.
        翻转一个单链表,如:1->2 输出 2->1;1->2->3 输出3->2->1。


题目解析:
        本人真的比较笨啊!首先想到的方法就是通过判断链尾是否存在,再新建一个链表,每次移动head的链尾元素,并删除head链表中的元素,一个字“蠢”,但好歹AC且巩固了链表基础知识。你可能遇见的错误包括:
        1.'ListNode' undeclared (first use in this function)
        nhead=(istNode*)malloc(sizeof(ListNode));    
                                    =>
        nhead=(struct ListNode*)malloc(sizeof(struct ListNode));
        2.Time Limit Exceeded
        在链表遍历寻找最后一个结点并插入新链表尾部中需要注意,建议的方法:
        q=head; while(q) {q=q->next;}
        p=(struct ListNode*)malloc(sizeof(struct ListNode));
        p->val=head->val; p->next=NULL; q=p;       
                                    =>
        q=head; while(q) {last=q; q=q->next;} 
        p=(struct ListNode*)malloc(sizeof(struct ListNode));
        p->val=head->val; p->next=NULL; last->next=p;
        通过借助last变量更直观,否则结果总是错误。而且此时q为next指向NULL,如果用到q->next=p就会出现RE错误,因为q都为NULL,哪来的q->next。第二个错误也可能是我个人的编程习惯吧!
        第二种方法更为推荐——直接翻转,还有一种递归方法自行提高。
        如下图所示,红色表示初始链表存在4个值[1, 2, 3, 4],蓝色表示初始指针first指向第一个元素、second指向第二个元素(head->next),third指向第三个元素;首先s->next=f断开链表并翻转指向第一个元素,同时f=s最后返回first。如果只有两个元素[1, 2]则执行"s->next=f; f=s;"后s=t=NULL返回f即可输出[2, 1]。



我的代码:
直接翻转方法
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode *first,*second,*third;
    if(head==NULL||head->next==NULL)
        return head;
    first = head;
    second = head->next;
    first->next = NULL;
    while(second!=NULL) {  //注意while(second)不能执行
        third = second->next;
        second->next = first;
        first = second;
        second = third;
    }
    return first;
}
"蠢"方法
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 //个人思路:判断链尾是否存在 翻转到一个新链表
struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode *nhead,*q,*p,*last,*nq,*np;
    int value;
    if(head==NULL||head->next==NULL)
        return head;
    q=head;
    nhead=NULL;     //创建新表头
    while(q->next) {
        //删除最后一个链尾结点
        p=q;
        while(p->next) {
            last=p;
            p=p->next;    
        }
        value=p->val;
        last->next=NULL;
        free(p);
        //插入行结点
        nq=nhead;
        while(nq) {
            last=nq;
            nq=nq->next;
        }
        if(nhead==NULL) { //创建表头
            np=(struct ListNode*)malloc(sizeof(struct ListNode));
            np->val=value;
            nhead=np;
            nhead->next=NULL;
        }
        else {           //插入结点
            np=(struct ListNode*)malloc(sizeof(struct ListNode));
            np->val=value;
            np->next=NULL;
            last->next=np;
        }
        //q结点循环前始终指向链表头
        q=head;
    }
    //最后一个结点及头结点head
    nq=nhead;
    while(nq) {
        last=nq;       //使用nq=np总是报错WR
        nq=nq->next;
    }
    np=(struct ListNode*)malloc(sizeof(struct ListNode));
    np->val=head->val;
    np->next=NULL;
    last->next=np;    //nq->next=np会报错RE 因为nq此时为next及null,而nq->next更不知道在哪
    return nhead;
}


(By:Eastmount 2015-9-14 晚上7点    http://blog.csdn.net/eastmount/ )

目录
相关文章
|
4月前
|
Python
【Leetcode刷题Python】25.K 个一组翻转链表
解决LeetCode "K 个一组翻转链表" 问题的三种方法:使用栈、尾插法和虚拟节点顺序法,并提供了每种方法的Python实现代码。
35 0
|
2月前
【LeetCode】整数翻转
【LeetCode】整数翻转
16 1
|
5月前
|
存储 C++
C++的list-map链表与映射表
```markdown C++ 中的`list`和`map`提供链表和映射表功能。`list`是双向链表,支持头尾插入删除(`push_front/push_back/pop_front/pop_back`),迭代器遍历及任意位置插入删除。`map`是键值对集合,自动按键排序,支持直接通过键来添加、修改和删除元素。两者均能使用范围for循环遍历,`map`的`count`函数用于统计键值出现次数。 ```
|
6月前
|
算法
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
|
6月前
|
存储 C++
C++的list-map链表与映射表
这篇教程介绍了C++中`list`链表和`map`映射表的基本使用。`list`链表可通过`push_front()`、`push_back()`、`pop_front()`和`pop_back()`进行元素的添加和删除,使用迭代器遍历并支持在任意位置插入或删除元素。`map`是一个键值对的集合,元素自动按键值排序,可使用下标操作符或`insert()`函数插入元素,通过迭代器遍历并修改键值对,同时提供`count()`方法统计键值出现次数。教程中包含多个示例代码以帮助理解和学习。
|
6月前
|
存储 机器学习/深度学习 算法
python 五种算法转置后翻转、层次旋转、递归分块、一次性旋转、环状替换 实现旋转图像【力扣题48】
python 五种算法转置后翻转、层次旋转、递归分块、一次性旋转、环状替换 实现旋转图像【力扣题48】
|
6月前
|
存储 算法 数据可视化
力扣156题最全解法:如何上下翻转二叉树(递归与迭代方法详解,附图解)
力扣156题最全解法:如何上下翻转二叉树(递归与迭代方法详解,附图解)
|
6月前
|
C++ 容器
【C++进阶】深入STL之list:高效双向链表的使用技巧
【C++进阶】深入STL之list:高效双向链表的使用技巧
61 0
|
6月前
25. K个一组翻转链表
25. K个一组翻转链表
|
6月前
|
算法 数据挖掘 Python
LeetCode题目25 hard:K个一组翻转链表 【分治策略 Python】
LeetCode题目25 hard:K个一组翻转链表 【分治策略 Python】