算法学习笔记【day4】

原视频

哈希表

哈希表的简单介绍(个人理解对于js当中就是简单的map)
1)哈希表在使用层面上可以理解为一种集合结构
2)如果只有key,没有伴随数握value,可以使用HashSet结构(C++中叫UnOrderedSet)
3) 如果既有key,又有伴随数据value,可以使用HashMap结构(C++中叫UnOrderedNap)
4)有无伴随数据,是HashMap和HashSet雅一的区别,底层的实际结构是一回事
5) 使用哈希表增 (put)、删(remove)、改(put) 和查(get)的操作,可以认为时间复杂度为O(1),但是常数时间比较大
6)放入哈希表的东西,如果是基础类型,内部按值传递,内存占用就是这个东西的大小
7)放入哈希表的东西,如果不是基础类型,内部按引用传递,内存占用是这个东西內存地 址的大小

有序表

有序表的简单介绍
1) 有序表在使用层面上可以理解为一种集合结构
2)如果只有key,没有伴随数据value,可以使用TreeSet结构(C++中叫OrderedSet)
3)如果既有key,又有伴随数据value,可以使用Treellep结构(C++中叫OrderedMap)
4)有无伴随数据,是TreeSet和Treelap唯一的区别,底层的实际结构是一回事
5)有序表和哈希表的区别是,有序表把key按照顺序組织起来,而哈希表完全不组织
5) 红黑树、AVL树、size-balance-tree和號表等都属于有序表结构,只是底层具体实现
不同
6)放入哈希表的东西,如果是基础类型,内部按值传递,内存占用就是这个东西的大小
7)放入哈希表的东西,如果不是基础类型,必须提供比较器,内部按引用传递,内存古 用是这个东西内存地址的大小
8)不管是什么底层具体实现,只要是有序表,都有以下固定的基本功能和固定的时间复 杂度

链表

单向链表

class Node {
    v value
    Node next
}

双向链表

class Node {
    v value
    Node next
    Node last
}

相关题目: 翻转链表
[打印有序链表的公共部分]

判断链表是否为回文链表

【题目】给定一个单链表的头节点head,请判断该链表是否为回文结构。
【例子】1->2->1,返回true;1->2->2->1,返回true;15->6->15,返回true;
1->2->3,返回false。
【思路】:用一个栈把该链表存下,存完之后每次pop出来和链表比对
【例子】如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1)。
考虑使用快慢指针 找到中点。然后再遍历到中点后改变下一个节点的指向改为指向上一个同时记录首位节点。然后通过首位遍历链表,判断是否一直相同,一直相同则为回文。额外控件复杂度为O(1)
算法学习笔记【day4】_第1张图片

快慢指针

在一个单向链表中,如何知道链表的中点在哪?设置一个快指针一次走两步,慢指针一次走一步,那么快指针走完的时候,慢指针走到的位置就是中点的位置,需要注意的是要根据数据的长度是基数和数据偶数是偶数时候进行特判

快慢指针也可以判断链表是否为有环无环,如果快指针 === 慢指针 就是有环,这里还能延伸当当快指针和慢指针相遇后,快指针回到原点,慢指针不动,接下来快慢指针都同时走一步,他们终将会在入环节点相遇()

将单向链表按某值划分成左边小、中间相等、右边大的形式

【题目】给定一个单链表的头节点head,节点的值类型是整型,再给定一个整数pivot。实现一个调整链表的西数,将链表调整为左部分都是值小于pivot的 节点,中间部分都是值等于pivot的节点,右部分都是值大于pivot的节点。

【进阶】在实现原问题功能的基础上增加如下的要求
【要求】调整后所有小于pivot的节点之间的相对顺序和调整前一样
【要求】调整后所有等于pivot的节点之间的相对顺序和调整前一样
【要求】调整后所有大于pivot的节点之间的相对顺序和调整前一样
【要求】时间复杂度请达到0(N),额外空间复杂度请达到0(1)。

复制含有随机指针节点的链表

【题目】一种特殊的单链表节点类描述如下

class Node {
    int value;
    Node next;
    Node rand;
}

rand指针是单链表节点结构中新增的指针,rand可能指向链表中的任意一个节 点,也可能指向null。给定一个由Node节点类型组成的无环单链表的头节点 head,请实现一个函数完成这个链表的复制,并返回复制的新链表的头节点。
【要求】时间复杂度0(N),额外空间复杂度0(1)

思路: 使用额外空间时,考虑使用map(js 中为Map结构不能是{}),key为老节点,value为新节点一个个复制,再遍历一个遍根据map一个个拼
不使用额外空间就比较屌了,1指向1复制 同时1复制指向1next,2指向2复制,同时2复制指向2next然后再遍历一遍拿出新链表
这里为什么不能直接复制是因为你复制1的时候,1的rand指向还没生成,你无法知道指向哪。

当然也可以使用hash表来判断入环节点在哪,遍历的时候顺便放到hash中,每次遍历的过程中看下hashmap 中寸没存,存过了就是入环节点。

两个单链表相交的一系列问题

【题目】给定两个可能有环也可能无环的单链表,头节点head1和head2。请实 现一个函数,如果两个链表相交,请返回相交的 第一个节点。如果不相交,返回null

【要求】如果两个链表长度之和为N,时间复杂度请达到O(N),额外空间复杂度
请达到O(1)。

【思路】因为如果有相交 那么后面的节点一定都相同(即两个链表一定是y字型)那么我们就先判断两个链表的尾是否相同。如果不同返回null 不同的话求两个链表的长度。然后让长的链表先走出长的距离,然后遍历

其他

链表这一张理解并不深入 有空还得看看这个https://zhuanlan.zhihu.com/p/...

你可能感兴趣的:(前端算法)