队列
1 循环队列
用数组做循环队列,这里发现还是在边界处理比较复杂,尤其在进行循环的条件设置
if (this.tail == this.len) this.tail = 0
2 最近请求次数
有个在边界指针的移动,不只是移动一个位置
// 如果 边界值 比左侧小 需要移动左侧指针
if ( sub3000 > 0 && headVal < sub3000 ) {
// 这里移动指针不只是移动一位 而是一直移动到符合要求为止
while (this.array[this.head] < sub3000) {
this.head++
}
}
链表
1 删除重复元素
思路解析:此链表已是升序,所以可以对其进行指针移动,当判断前后节点数值相同时,指针持续移动直到知道有不同值的那个节点,更新next指针即可
这里有个部分是关于0的处理,联系的时候忽略了0 ,其实应该按照 != null 进行判断,所以多次提交失败
2 旋转链表
从例子可以看出来, 其实就是遍历K次,每次把尾部节点移动到头部。
这里有个逻辑
let current = head
while (current && current.next) {
current = current.next
count++
}
let remainderCount = k % count
是算了一次余数,如果K值特别大的时候,其实是求了余即可
还有一个点在获取最后一个节点的前一个节点的边界判断
while (cur && cur.next && cur.next.next) {
cur = cur.next
}
1 每次走两步
let nextNode = current.next.next
....
current = nextNode
2 记录那个左边 在两个节点交换位置后 需要跟左侧已经处理完的那截连起来
moveN.next = right
moveN = left
4 隔离链表
体会一下虚拟头节点的好用
let dummyHead1 = new ListNode(0)
其实这个题目表述不清晰,翻译大白话就是 以 X 为界 拆分为一波大 一波小两个链表,最后将链表链接成一个进行返回
5 并查集 - 省份数量
大致思路是,将城市相连的i和j 进行连接操作
for(let i=0;i<len;i++){
for(let j=0;j<len;j++){
if (isConnected[i][j] == 1) {
unions.merge(i, j)
}
}
}
然后省份数量是 1 去重后的父节点 2 直接遍历查找根节点
6 并查集 - 等式方程的可满足性
处理思路: == 进行连接。然后剩余 != 的判断是否是同一个集合
这里用染色法写的,合并操作写出一个BUG来
注意要先保存 colorX colorY
merge (x, y) {
const colorX = this.color[x]
const colorY = this.color[y]
for(let i= 0; i< this.n; i++) {
const node = this.node[i]
if ( this.color[node] == colorY) {
this.color[node] = colorX
}
}
}
不要这么写
if ( this.color[node] == this.color[x]) {
this.color[node] = this.color[y]
}