算法打卡|Day4 链表part02
Day4 链表part02
今日任务
● 24. 两两交换链表中的节点
● 19.删除链表的倒数第N个节点
● 面试题 02.07. 链表相交
● 142.环形链表II
Problem: 24. 两两交换链表中的节点
思路
1.迭代法就要注意画图!画图!还是画图!另外迭代的次序不要忘记,链表迭代统一从左往右迭代。用三个结点去一遍遍迭代
2.使用递归法,先交换前两个结点,然后指向递归好的链表就行。
解题方法
迭代或递归
Code
/**
时间复杂度:O(n)
空间复杂度:O(1)
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
auto dummy = new ListNode(0,head);
ListNode* a = dummy;
while (a->next != nullptr && a->next->next != nullptr){
ListNode* b = a->next;
ListNode* c = a->next->next;
a->next = c;
b->next =c->next;
c->next =b;
a = b;
}
return dummy->next;
}
};
Code
/**
时间复杂度:O(n)
空间复杂度:O(n)
拓展
*/
//思路:两两交换链表中的节点,拿第一个节点头节点head与第二个节点newHead(newHead = head.next) 来讲,需要将head与newHead交换位置,使newHead变成链表中的头节点,head变成第二个节点,然后head再指向已经处理好的链表,以此类推,递归调用本身,直到最后只剩下一个节点或者为空,结束返回新的头指针,也就是newHead
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
//递归边界条件, 有2个结点才需要交换
if(head == nullptr || head->next == nullptr){
return head;
}
ListNode* newHead =head->next;
head->next = swapPairs(newHead->next);
newHead->next = head;
return newHead;
}
};
Problem: 19. 删除链表的倒数第 N 个结点
思路
首先我们要用快慢指针,快指针先走,慢指针再和快指针同步走。不过,要删除一个节点需要走到那个节点的前一个,所以我们要让快指针多走一个。比如要删除倒数第二个节点,我们就要让快指针先走3格。最后记得虚拟头结点,因为可能涉及到真实头结点的删除。
解题方法
双指针
Code
/**
时间复杂度: O(n)
空间复杂度: O(1)
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyhead = new ListNode(0, head);
ListNode* fast = dummyhead;
ListNode* slow = dummyhead;
n++;
while(n-- && fast != nullptr){
fast = fast->next;
}
while(fast!=nullptr){
slow = slow->next;
fast = fast->next;
}
slow->next = slow->next->next;
//此处不能head,因为如果只有1个节点,应该返回空,而不是原来的hea(head发生了改变);并且slow改变的是虚拟节点后续的链表
return dummyhead->next;
}
};
Problem: 面试题 02.07. 链表相交
思路
如果有公共结点肯定是在后面重叠,且后面部分都是共同的。
方法1:先计算出两个链表的长度,可以让比较长的先走两个链表长度之差的步数,两个再一起走。
方法2:不同部分为a, 和b,公共部分为c;a + c + b = b + c + a;让两个一起走,a走到头就转向b, b走到头转向a,则在公共部分相遇。
解题方法
双指针法
复杂度
- 时间复杂度:
$O(2n)$
- 空间复杂度:
$O(1)$
Code
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *p1 = headA;
ListNode *p2 = headB;
while (p1 != p2) {
if(p1 != NULL)//p1没有走到结尾
p1 = p1->next;//p1指向下一个节点
else//p1走到结尾
p1 = headB;//p1指向另一个链表头
if(p2 != NULL)//p2没有走到结尾
p2 = p2->next;//p2指向下一个节点
else //p2走到结尾
p2 = headA;//p2指向另一个链表头
}
return p1;
}
};
Problem: 24. 两两交换链表中的节点
思路
1.迭代法就要注意画图!画图!还是画图!另外迭代的次序不要忘记,链表迭代统一从左往右迭代。用三个结点去一遍遍迭代
2.使用递归法,先交换前两个结点,然后指向递归好的链表就行。
解题方法
迭代或递归
Code
/**
时间复杂度:O(n)
空间复杂度:O(1)
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
auto dummy = new ListNode(0,head);
ListNode* a = dummy;
while (a->next != nullptr && a->next->next != nullptr){
ListNode* b = a->next;
ListNode* c = a->next->next;
a->next = c;
b->next =c->next;
c->next =b;
a = b;
}
return dummy->next;
}
};
Code
/**
时间复杂度:O(n)
空间复杂度:O(n)
拓展
*/
//思路:两两交换链表中的节点,拿第一个节点头节点head与第二个节点newHead(newHead = head.next) 来讲,需要将head与newHead交换位置,使newHead变成链表中的头节点,head变成第二个节点,然后head再指向已经处理好的链表,以此类推,递归调用本身,直到最后只剩下一个节点或者为空,结束返回新的头指针,也就是newHead
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
//递归边界条件, 有2个结点才需要交换
if(head == nullptr || head->next == nullptr){
return head;
}
ListNode* newHead =head->next;
head->next = swapPairs(newHead->next);
newHead->next = head;
return newHead;
}
};
算法打卡|Day4 链表part02的更多相关文章
- cc150:实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针
实现一个算法来删除单链表中间的一个结点,仅仅给出指向那个结点的指针. 样例: 输入:指向链表a->b->c->d->e中结点c的指针 结果:不须要返回什么,得到一个新链表:a- ...
- 算法:输入一个链表,输出该链表中倒数第k个结点。
算法:输入一个链表,输出该链表中倒数第k个结点.<剑指offer> 思路加到注释里面了: 1:两个if判断是否返回值为空,首个为空,没有第k个值: 2:for循环找到倒数第k个值,返回为a ...
- LeetCode初级算法的Python实现--链表
LeetCode初级算法的Python实现--链表 之前没有接触过Python编写的链表,所以这里记录一下思路.这里前面的代码是和leetcode中的一样,因为做题需要调用,所以下面会给出. 首先定义 ...
- 数据结构与算法之美 06 | 链表(上)-如何实现LRU缓存淘汰算法
常见的缓存淘汰策略: 先进先出 FIFO 最少使用LFU(Least Frequently Used) 最近最少使用 LRU(Least Recently Used) 链表定义: 链表也是线性表的一种 ...
- 算法之python创建链表实现cache
算法之python创建链表实现cache 本节内容 问题由来 解决思路 实现代码 总结 1. 问题由来 问题起因于朋友的一次面试题,面试公司直接给出两道题,要求四十八小时之内做出来,语言不限,做出来之 ...
- JavaScript 版数据结构与算法(三)链表
今天,我们要讲的是数据结构与算法中的链表. 链表简介 链表是什么?链表是一种动态的数据结构,这意味着我们可以任意增删元素,它会按需扩容.为何要使用链表?下面列举一些链表的用途: 因为数组的存储有缺陷: ...
- 实用算法系列之RT-Thread链表堆管理器
[导读] 前文描述了栈的基本概念,本文来聊聊堆是怎么会事儿.RT-Thread 在社区广受欢迎,阅读了其内核代码,实现了堆的管理,代码设计很清晰,可读性很好.故一方面了解RT-Thread内核实现,一 ...
- 数据结构和算法 c#– 1.单项链表
1.顺序存储结构 Array 1.引用类型(托管堆) 2.初始化时会设置默认值 2.链式存储结构 2.1.单向链表 2.2.循环链表 2.3.双向链表
- 008实现一个算法从一个单链表中返回倒数第n个元素(keep it up)
我们维护两个指针, 它们之间的距离为n. 然后.我将这两个指针同步地在这个单链表上移动,保持它们的距离 为n不变. 那么, 当第二个指针指到空时.第一个指针即为所求. #include <ios ...
- Java数据结构和算法(七)——链表
前面博客我们在讲解数组中,知道数组作为数据存储结构有一定的缺陷.在无序数组中,搜索性能差,在有序数组中,插入效率又很低,而且这两种数组的删除效率都很低,并且数组在创建后,其大小是固定了,设置的过大会造 ...
随机推荐
- 【RS】多光谱波段和全色波段的区别
<p><strong>1.全色波段(Panchromatic Band)</strong></p> 全色图像是单通道的(即单波段灰色影像),其中全色是指 ...
- 一文搞懂V8引擎的垃圾回收机制
前言 我们平时在写代码的过程中,好像很少需要自己手动进行垃圾回收,那么V8是如何来减少内存占用,从而避免内存溢出而导致程序崩溃的情况的.为了更高效地回收垃圾,V8引入了两个垃圾回收器,它们分别针对不同 ...
- 解放计算力:使用并行处理提升python for循环速度
Python 是一门功能强大的编程语言,但在处理大规模数据或复杂计算任务时,性能可能成为一个瓶颈.幸运的是,Python 提供了多种方法来提升性能,其中之一是利用并行处理来加速循环操作.本文将介绍如何 ...
- 大数据实战手册-开发篇之IO
2.4 sparkContext IO:读 2.4.1 textFile # Load a text file and convert each line to a Row. lines = sc.t ...
- Java 访问控制权限修饰符
1.访问控制权限修饰符来控制元素的访问范围 2.访问控制权限修饰符包括: public 表示公开的,任何位置都可以可以访问 protected 同包,子类 缺省 同包 private 表示私有的,只能 ...
- PHP如何获取短网址跳转之前的网址?
现在有很多的短网址应用,点击就跳转到缩短之前的网址了,那今天我们就来看一下,PHP如何**短网址跳转之前的网址,其实也很简单,就是用php的get_headers 函数,取得Response Head ...
- 最近很火的开源培训系统,支持免费商用,3个月1000star!
项目简介 PlayEdu 开源培训系统自发布以来,3个月内帮助上千位开发者部署了私有化培训平台,并在 Github 上获得了1000star. 项目地址 Github 地址:https://githu ...
- 图像格式及Matlab的格式转换
1. matlab图像保存说明 matlab中读取图片后保存的数据是uint8类型(8位无符号整数,即1个字节),以此方式存储的图像称作8位图像,好处相比较默认matlab数据类型双精度浮点doubl ...
- 部署 rsyslog 日志服务
ubuntu 服务端 + Centos 客户端 参考文档: ubuntu 20.04 搭建 rsyslog 服务器 CentOS7下搭建Rsyslog Server记录远程主机系统日志
- sudo:pam_open_session Permission denied 与 Too many open files
sudo:pam_open_session Permission denied 一,验证 sudo 权限失败: /etc/sudoers 文件未给相关用户配置权限. 打开 /etc/sudoers 文 ...


