剑指offer—单链表反转的三种实现方法

单链表的反转可以用递归、非递归和栈的方法实现

链表节点定义:

struct ListNode{
    int val;
    Node* next;
    ListNode(int x):val(x),next(nullptr){}
}

1、栈

ListNode* reverseList(ListNode* head) {
    if(!head || !head->next)
       	return head;
    stack<ListNode*>stk;
    //将链表的结点全部压进栈
    while(head){
        stk.push(head);
        head = head->next;
    }
    ListNode*cur,*nxt;
    cur = nxt = stk.top();
    stk.pop();
    while(!stk.empty()){
        nxt ->next = stk.top();
        nxt = nxt ->next;
        stk.pop();
    }
    //最后一个结点的next记得要指向nullptr
    nxt ->next =nullptr;
    return cur;
}

2、递归

利用递归,直到链表的最后一个节点,用一个指针指向该节点,作为反转后的链表的头节点

在递归返回的过程中,让该节点的下一个节点指向该节点\((head->next->next=head)\),

并让该节点指向\(NULL\)。这样就从链表尾部一步步实现了反转

Ps:图片来自网络侵权删

ListNode* reverseList(ListNode* head) {
    if(head==NULL || head->next==NULL)
        return head;
    ListNode* ptr=reverseList(head->next);
    head->next->next=head;
    head->next=NULL;

	return ptr;
}

3、双指针

利用两个结点指针和一个中间结点指针 \(temp(用来记录当前结点的下一个节点的位置)\),分别指向当前结点和前一个结点,每次循环让当前结点的指针域指向前一个结点即可

ListNode* reverseList(ListNode* head) {
    ListNode* cur=head;
    ListNode* pre=nullptr;
    while(cur)
    {
        ListNode* tmp=cur->next;
        cur->next=pre;
        pre=cur;
        cur=tmp;
    }
    return pre;
}

原文地址:https://www.cnblogs.com/RioTian/p/12614568.html

时间: 2024-08-11 05:38:00

剑指offer—单链表反转的三种实现方法的相关文章

【剑指offer】链表倒数第k个节点

转载请注明出处:http://blog.csdn.net/ns_code/article/details/25662121 在Cracking the Code Interview上做过了一次,这次在九度OJ上测试,AC. 题目描述: 输入一个链表,输出该链表中倒数第k个结点.(hint: 请务必使用链表.) 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行为两个整数n和k(0<=n<=1000, 0<=k<=1000):n代表将要输入的链表元素的

剑指offer之链表

//剑指offer 之 链表 //面试题6 从尾到头打印链表 /***************************************************************************************** 问题描述: 输入一个链表的头节点,从尾到头反过来打印出每个节点的值 链表节点定义如下: struct ListNode{ int m_nValue; ListNode* m_pNext; }; *******************************

剑指offer (5) 链表插入删除

我们在操作链表的时候,必须注意以下事项: 1. 链表指针为NULL的情况 2. 插入删除涉及到 链表第一个节点时,需要修改 链表的第一个节点: a. 因为 c语言都是传值的,如果需要修改一个变量,就必须通过 指向该变量的指针(即该变量的地址) 例如:例如 修改 int a,则输入参数必须是 int* a, 修改a 则是: *a = b; (b为int) 我们需要修改一个指针时,就必须通过 该指针的地址,也就是 指向该指针的指针,即二级指针 例如  修改 int* a, 则输入参数必须是 int*

单链表反转的2种方法

1 public class ReverseDemo { 2 3 /** 4 * 单链表反转的两种方法 5 */ 6 public static void main(String[] args) { 7 Node head =new Node("a"); 8 Node node2=new Node("b"); 9 Node node3=new Node("c"); 10 head.setNext(node2); 11 node2.setNext(

【Java】 剑指offer(22) 链表中倒数第k个结点

正文 本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入一个链表,输出该链表中倒数第k个结点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点.例如一个链表有6个结点,从头结点开始它们的值依次是1.2.3.4.5.6.这个链表的倒数第3个结点是值为4的结点. 思路 第一直觉是先从头开始遍历,计算链表个数n,然后重新遍历,第n-k+1个结点即为所需要的结点.但是需要遍历2次.后面采用了栈进行实现该

两个链表的第一个公共结点(剑指offer)+链表

两个链表的第一个公共结点 参与人数:1171时间限制:1秒空间限制:32768K 通过比例:31.25% 最佳记录:0 ms|0K(来自  running) 题目描述 输入两个链表,找出它们的第一个公共结点. 链接:http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

剑指Offer对答如流系列 - 反转链表

面试题24:反转链表 题目描述 定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点 链表结构 public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } 问题分析 头插法是反转链表非常经典的一种手段,这里演示一下吧,毕竟这个在JDK源码中也能遇见. 核心代码如下: ListNode Inverse(ListNode L) { ListNode p,

剑指offer 复杂链表的复制

题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空) 思路:要进行深拷贝,需要每次都new一个节点出来,利用unordered_map, 2.3 138. Copy List with Random Pointer https://leetcode.com/problems/copy-list-with-random-poi

剑指offer (15) 链表倒数第K个结点

题目: 输入一个链表,输出该链表中倒数第k个结点 (注意:我们将链表最末一个结点记为 倒数第1个结点,也就是k从1开始计数) 解题分析: 方法一:遍历链表两次,第一次统计链表结点个数,第二次遍历就可以找到倒数第K个结点 方法二:遍历链表一次 我们使用两个指针,第一个指针从链表的头指针开始遍历向前走k-1步,第二个指针一直指向链表开头并保持不动 从第k步开始,两个指针同时向前走,这时 两个指针之间的距离一直是k-1 当第一个指针到达链表尾结点时,第二个指针指向链表倒数第k个结点 1 ListNod