当前位置:网站首页>牛客网刷题(一)
牛客网刷题(一)
2022-07-31 15:59:00 【std i hurt o love】
重排链表
解法一:暴力
观察排序后的序列我们可以发现,第一个节点后接最后一个节点,第二个节点后接倒数第二个节点,以此类推。故我们可以每次都找到最后一个节点并把它接在当前节点的后面
我们用一个指针p指向头节点,每次找到链表的最后一个节点并将它接在p所指节点的后面,然后p再指向下一个节点,直到p后面的节点数小于两个时停止
class Solution {
public:
void reorderList(ListNode *head) {
ListNode* p = head;
while(p){
if(p->next && p->next->next){
// 若p后面至少有两个节点
ListNode *pre = p->next, *cur = p->next->next;
while(cur->next){
// 找到最后一个节点cur, pre指向倒数第二个节点
cur = cur->next;
pre = pre->next;
}
// 将cur接在p后面
pre->next = nullptr;
cur->next = p->next;
p->next = cur;
p = p->next->next;
}
else break;
}
}
};
时间复杂度:O(n^2), n为节点数,每次找最后一个的时间复杂度为O(n),故总时间复杂度为O(n^2)
空间复杂度:O(1)
解法二:(线性表)
方法一的缺陷在于链表不能通过下标访问元素,故每次找到最后一个节点都很花费时间,因此我们想到可以用线性表来存储节点指针,然后再重新连接链表即可
实现细节:我们先将每个节点指针放入数组中,然后使用双指针算法每次取出前后对应的两个节点并让前一个节点指向后一个节点,然后用一个指针pre表示上一部分的尾节点指针,若pre不为空,说明前面有一段链表,让pre指向取出的前一个节点即可,再令pre为取出的后一个节点,以此类推,最后记得让pre指向空,当然前提是pre自身不为空
class Solution {
public:
void reorderList(ListNode *head) {
vector<ListNode*> vec; // 创建线性表
ListNode* cur = head;
while(cur){
// 将节点指针放入线性表
vec.emplace_back(cur);
cur = cur->next;
}
ListNode* pre = nullptr;
int i = 0, j = vec.size() - 1;
while(i <= j){
// 使用双指针算法重连链表
vec[i]->next = vec[j];
if(pre) pre->next = vec[i];
pre = vec[j];
i++, j--;
}
if(pre) pre->next = nullptr; // 尾节点指向空指针
}
};
时间复杂度:O(n), n为链表节点数,双指针算法的时间复杂度为O(n)
空间复杂度:O(n), 线性表使用的空间
解法三:(快慢指针、链表翻转、链表合并)
我们可以先通过快慢指针找到链表中点,然后将链表一分为二,再将第二段链表翻转,最后将两段链表交叉合并为一条即可
这种做法涉及到了快慢指针求链表中点,链表的原地翻转和链表的交叉合并,综合性很强,考察了我们指针使用的熟练度和基本功
为了方便理解,我用动图来帮助大家弄懂基本的实现原理,关于链表原地翻转的算法,我将在最后用一张动图来演示
class Solution {
public:
void reorderList(ListNode* head) {
if(!head) return;
ListNode* mid = GetMid(head); // 得到链表的中点
ListNode *p1 = head, *p2 = mid->next;
mid->next = nullptr; // 断开链表
p2 = ReverseList(p2); // 翻转后一段链表
MergeList(p1, p2); // 交叉合并两条链表
}
ListNode* GetMid(ListNode* head) {
// 返回链表中点
ListNode *slow = head, *fast = head;
while(fast->next && fast->next->next){
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
ListNode* ReverseList(ListNode* head) {
// 链表的原地翻转
if(!head) return head;
ListNode *pre = head, *cur = head->next;
while(cur){
head->next = cur->next;
cur->next = pre;
pre = cur;
cur = head->next;
}
return pre;
}
void MergeList(ListNode *l1, ListNode *l2) {
// 交叉合并两条链表
ListNode *tmp1, *tmp2;
while(l1 && l2){
tmp1 = l1->next;
tmp2 = l2->next;
l1->next = l2;
l2->next = tmp1;
l1 = tmp1;
l2 = tmp2;
}
}
};
时间复杂度:O(n),快慢指针,链表合并,翻转链表的时间复杂度都是O(n)的
空间复杂度:O(1)
边栏推荐
- 多主复制的适用场景(2)-需离线操作的客户端和协作编辑
- Unity中实现点选RenderTexture中的3D模型
- Linux check redis version (check mongodb version)
- Why don't you make a confession during the graduation season?
- [Meetup Preview] OpenMLDB+OneFlow: Link feature engineering to model training to accelerate machine learning model development
- Kubernetes principle analysis and practical application manual, too complete
- C语言-函数
- LeetCode_733_Image rendering
- MySQL multi-table union query
- 11 pinia使用
猜你喜欢

Dialogue with Zhuang Biaowei: The first lesson of open source

Premiere Pro 2022 for (pr 2022)v22.5.0

6-22 Vulnerability exploit - postgresql database password cracking

11 pinia use

【C语言】LeetCode27.移除元素

gerrit中如何切换远程服务器

border控件的使用

研发过程中的文档管理与工具

SringMVC中个常见的几个问题

Kubernetes principle analysis and practical application manual, too complete
随机推荐
i.MX6ULL driver development | 33 - NXP original network device driver reading (LAN8720 PHY)
Graham's Scan method for solving convex hull problems
OPPO在FaaS领域的探索与思考
更新数据表update
百度网盘网页版加速播放(有可用的网站吗)
腾讯云部署----DevOps
Replication Latency Case (3) - Monotonic Read
Kubernetes常用命令
【C语言】LeetCode27.移除元素
深度学习机器学习理论及应用实战-必备知识点整理分享
Qt practical cases (54) - using transparency QPixmap design pictures
Use of radiobutton
JVM parameter analysis Xmx, Xms, Xmn, NewRatio, SurvivorRatio, PermSize, PrintGC "recommended collection"
2022年必读的12本机器学习书籍推荐
Website vulnerability repair service provider's analysis of unauthorized vulnerability
Insert into data table to insert data
Kubernetes common commands
在资源管理类中提供对原始资源的访问——条款15
Applicable scenario of multi-master replication (2) - client and collaborative editing that require offline operation
Implementing distributed locks based on Redis (SETNX), case: Solving oversold orders under high concurrency