从尾到头打印链表 之 “C++代码+思路解析 ”(允许原地修改链表)

从尾到头打印链表 之 “C++代码+思路解析 ”(允许原地修改链表)

上一篇 从尾到头打印链表 (第一种情况 不允许原地打印链表)

希望我的文字始终给您带来画面感。

其实做算法题的过程也是在考验我们的大脑日常解决问题的能力,懂不懂得将生活中碰到的难题拆分,一一解决

今日感悟

//不要去刻意记忆代码句,先用起来,积累框架,慢慢拿出来用。
//不是所有的框架都是一样的,也要学会适应不同的变化。

题目开始咯!

  题目描述:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。

//这里敲黑板,千万注意:我们做算法题 ,最基本的也是最关键的题目一定要 理解准确。这道题涉及到允不允许原地修改链表,所以分为以下两种情况。这里是第二种情况。

 第二种情况:允许原地修改链表,那么只需要用三个指针来解决。

代码实现部分:

//5月9日
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre = nullptr;
        ListNode* cur = head;
        ListNode* next = nullptr;
        while(cur)
        {
            next = cur->next;
            
            cur->next = pre;
            
            pre = cur;
            cur = next;
        }
        
        return pre;
    }
};

思路解析部分:

我不知道大家的写算法思路是思维习惯和先后顺序是怎样的,我会习惯将代码拆分成小的代码块进行 ,再进行逻辑组合安装。当然这里无法评判哪种一定是正确的,这里我想分享一下:我个人认为最快的写代码顺序。

第一步:我会先搞清楚题目 ,需要我给它一个什么,定下来整体的框架。

这道题的第二种情况是允许原地修改链表,那么只需要返回传进来的链表就OK了,只不过这个链表被操作了一番。

那第一步函数整体的框架就出来咯!

class Solution {
public:
    ListNode* reverseList(  ) {
      
    .............................................
        
     return 头指针;//链表被原地操作,此时的头指针已经不是head了
    }
};

这里的第二步:我会把参数定下来,进到函数体首先就检查参数合不合法。

加入 if 语句检验参数 链表指针 head 是否为空。


class Solution {
public:
    ListNode* reverseList( ListNode* head) {
        if( !head )
        {
         return head;
        }
  
    .............................................
        return 头指针;
    }
};

第三步:给框架里面填上语句块。发挥( if,while,for…)语句的作用,语句其实就是思考逻辑的实现。

原地反转链表的逻辑就是把链表的数值比如-1-2-3-4-5-变成-5-4-3-2-1-。这里设置三个指针 ,前后中分别用cur,pre和next来表示。

1 填入 这块代码,使用while 语句做不断重复做两件事。

第1件事:使得当前结点的后继结点变成前驱结点,也就是2的后面不连3,要连1。用这句代码来实现这件事:cur->next = pre;

第2件事:不断推动三个指针向后走。用这三句代码来实现。
1next = cur->next; …(第一件事)…2 pre = cur; 3 cur = next;
大家都看出来了这三句是有顺序的。进入循环时一定要先把cur->next保存起来,使next先后移一步,不然下一步cur的后继结点的改变会让next指向乱掉。然后前指针和当前指针一起向后移动。

        
        while ( cur )
		{
			next = cur->next; 
			cur->next = pre;  //使当前结点的后继结点变成前驱结点。

			pre = cur;
			cur = next;
		}

第四步:抠细节,这里给加上定义,附上初值。

1 给变量加上定义+赋值。

        ListNode* pre = nullptr;
		ListNode* cur = head;
		ListNode* next = nullptr;

此题总结:

这道题目最大的难点就在于拆分语句的四句代码 ,怎样安排三指针的移动顺序,还有就是进入循环体就一定要先把当前结点的后继结点保存起来。

算法题经验:

我做算法题是先搞清楚题意,安排总框架,然后把解决办法拆分成一个个步骤,再把每个步骤落实到代码块,最后填充细节。

这样可以保证算法题做下来的整个过程中我们的整个思路是清晰的,不会让看似复杂的算法在我们的大脑中留下坏印象,使我们丧失兴趣。

其实做算法题的过程也是在考验我们的大脑日常解决问题的能力,懂不懂得将生活中碰到的难题拆分,一一解决。

上一篇 从尾到头打印链表(第一种情况 不允许原地打印链表)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章