算法--链表

2022/9/5 14:24:17

本文主要是介绍算法--链表,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

 

 

 

方法一:构造链表

如果此类型的题出现在笔试中,如果内存要求不高,可以采用如下方法:
可以先用一个vector将单链表的指针都存起来,然后再构造链表。
此方法简单易懂,代码好些。

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
    if(pHead->next==NULL || pHead==NULL) return pHead; //首先判断是否为空
      vector<ListNode*>v; //创建一个数组
        while(pHead){ //把数据中的元素全部放入到数组中去
            v.push_back(pHead);
            pHead = pHead->next;
        }
        reverse(v.begin(), v.end());  //反转vector,也可以逆序遍历
        ListNode *head = v[0]; //指定第一个元素
        ListNode *cur = head; 
        for(int i=1;i<v.size();++i){ //构造链表
            cur->next = v[i]; //当前节点的下一个指针指向下一个节点
            cur = cur->next;//当前节点后移
        } //将数组的逆序之后的元素链接起来
        cur->next = nullptr; //最后一个节点指向为空
        return head; //返回列表
    }
};

  

方法二:正规解法

但是面试的时候,上一种解法当然不行。此题想考察的是:如何调整链表指针,来达到反转链表的目的。
初始化:3个指针
1)pre指针指向已经反转好的链表的最后一个节点,最开始没有反转,所以指向nullptr
2)cur指针指向待反转链表的第一个节点,最开始第一个节点待反转,所以指向head
3)nex指针指向待反转链表的第二个节点,目的是保存链表,因为cur改变指向后,后面的链表则失效了,所以需要保存
接下来,循环执行以下三个操作
1)nex = cur->next, 保存作用
2)cur->next = pre 未反转链表的第一个节点的下个指针指向已反转链表的最后一个节点
3)pre = cur, cur = nex; 指针后移,操作下一个未反转链表的第一个节点
循环条件,当然是cur != nullptr
循环结束后,cur当然为nullptr,所以返回pre,即为反转后的头结点
这里以1->2->3->4->5 举例:
图片说明
图片说明
图片说明
图片说明
中间都是重复步骤,省略了。。。


代码

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution { public:     ListNode* ReverseList(ListNode* pHead) {         ListNode *pre = nullptr;         ListNode *cur = pHead;         ListNode *nex = nullptr; // 这里可以指向nullptr,循环里面要重新指向         while (cur) {             nex = cur->next;             cur->next = pre;             pre = cur;             cur = nex;         }         return pre;     } };

时间复杂度:O(n), 遍历一次链表
空间复杂度:O(1)

 



这篇关于算法--链表的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程