面试官: “反转链表”有哪些实现方式?

        hello大家好,我是小慕呀,愉快的周末结束啦,明天得去上班咯! 最近老是在微博热搜中看到“躺平”一词,出现的次数太多太多了,多的都数不清了,我们一起看下图 

​ 

 

 

 

然后看微博评论的时候看到很多好笑的,特别好笑,我随便列出几个好笑的 

你们都躺平,我赚谁的培训费?

 

只要我躺平,镰刀就割不到我!

 

我现在听什么马云俞敏洪之类讲话我就烦躁想抽他们!

 

你们随意,我先躺为敬

 

资本家还是别发声了,他屁股都是歪的

 

我觉得吧,大家讨厌的不是资本家也不是有钱人,本质上是讨厌自己怎么没有成为这类人。俗话说“屁股决定脑袋”嘛,说的大概也是这个意思,所处位置不同,想法不同,可以理解的,哈哈!!!

 

好啦,和大家唠嗑了一会儿了,废话不多说了,那今天晚上我们加个餐,学习一下“反转链表”呗!

 

所谓反转链表,就是将链表整体“反过来”,将头变成尾、尾变成头,如下图所示

 

一、利用“栈”的特性来实现

 我们都知道栈是“先进后出”的,刚好适用于将线性表的顺序颠倒这类问题

 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; //这个时候node已经变成新链表的最后一个节点了    return dummy;}

 

二、利用“头插法”来实现

  不熟悉头插法的朋友们,看下图即可明白啥是“头插法”

 

实现代码如下

struct ListNode *reverseList(struct ListNode* head) {  struct ListNode *newHead = NULL;  struct ListNode *node;  while (head != NULL) {    //1. 对之前的链表做头删    node = head;    head = head->next;    //2. 对新链表做头插    node->next = newHead;    newHead = node;  }  return newHead;}

 

三、利用“三指针”来实现

首先让P1指针指向链表的头结点,让P2指向链表的第二个节点,让P0指向链表的尾部

 

然后将P1和P2之间的那个指针给干掉,然后再让P1所指的那个节点的next箭头指向P0,如下图,(让P1节点和P0节点之间加一个箭头,就相当于让头结点指向了尾结点,这样不就有点反转的意思了吗?)

 

然后把P2,P1指针往后移一步,分别指向下一个节点,然后让P0指向链表的头部,再然后就是在P0和P1之间加一个红色箭头,如下图所示

然后一直把P2,P1,P0指针依次往后挪动,一边挪,一边加红色箭头,如下图所示,看红色的箭头,这样不就达到了链表反转的效果了吗?

 

代码如下:

struct ListNode *reverseList(struct ListNode* head) {  if (head == NULL) {    return NULL;  }  struct ListNode *p0 = NULL;  struct ListNode *p1 = head;  struct ListNode *p2 = head->next;  while (p1 != NULL) {    p1->next = p0;    p0 = p1;    p1 = p2;    if (p2 != NULL) {      p2 = p2->next;    }  }  return p0;}

 

四、利用“递归法”来实现

递归说白了就是“套娃”,所以想要学好递归,首先把套娃玩具玩它个几百遍,哈哈, 下图就是递归的思想。

 

下面的实现代码也是按上图的思想来实现的

 1  public ListNode reverseList(ListNode head) { 2    //终止条件 3    if (head == null || head.next == null) 4        return head; 5    //保存当前节点的下一个结点 6    ListNode next = head.next; 7    //从当前节点的下一个结点开始递归调用 8    ListNode reverse = reverseList(next); 9    //reverse是反转之后的链表,因为函数reverseList表示的是对链表的反转,所以反转完之后next肯定11    // 是链表reverse的尾结点,然后我们再把当前节点head挂到next节点的后面就完成了链表的反转。13    next.next = head;14    //这里head相当于变成了尾结点,尾结点都是为空的,15    //否则会构成环16    head.next = null;17    return reverse;18}

 

好啦,今天的内容到这里就结束了,行百里者半九十,请不要半途而废,好吗?

     历史推文

“快慢指针法“”的一些骚操作

    都2021年了,你还不懂幂等性问题的解决方案?

 为啥Spring事务失效了,你踩坑了吗?

    今天你又被内卷了吗?“躺平”好不好?

        Eureka和Zookeeper到底有什么区别 ?

     听说你还不懂什么是CAP理论?

     TCP三次握手、四次挥手很难?NO

  位运算的奇“赢”技巧

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java全栈研发大联盟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值