一直都知道算法对程序员来说很重要,但是自己刷题一直都是断断续续,很难坚持,最近报了个算法班,老师带着刷题,轻松不少,今天来做个小总结。
链表数据结构
关于链表数据结构的知识,我们很多人应该在大学的数据结构课程中就已经学习过了,这里做个简单介绍。
链表,顾名思义就是一种如同铁链般的结构,一环扣一环,每一个链节点都会被上一个节点连接,而它本身也会去链接下一个节点,如图:
每一个节点,分为存储该节点数据的数据域和指向下一个节点的指针域。在JS中,我们可以这么来表示一个链表结构:
class ListNode{
constructor(val){
this.val = val // 数据域
this.next = null // 指针域
}
}
const Node1 = new ListNode(1) // 1 -> null
const Node2 = new ListNode(3) // 2 -> null
Node1.next = Node2
console.log(Node1) // 1 -> 2 -> null
下面来看两个链表相关的题:
141. 环形链表
一、题目描述
给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。如下图:
二、解题思路
这道题可以用双指针来完成,即我们定义两个指针,这两个指针,一个每次向链表的尾部移动一个节点,另一个每次移动两个节点,此时: 1.如果不是环形链表,指针最终会指向null. 2.如果是环形链表,两个指针最终都会进入环中,同时因为指针移动速度不同,快的指针最终会追上慢的指针。 所以我们只需要判断指针是否是null,以及两个指针是否会指向同一个内存。 代码如下:
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var hasCycle = function(head) {
if(head === null || head.next === null) return false //链表为null,或链表只有一个节点都不会是环形链表
let p = q = head
do{
p = p.next
q = q.next.next
}while(q != p && q && q.next )
return q === p //如果不相等,说明节点循环结束,没有环,相等则说明,两个指针在环中相遇
};
202. 快乐数
一、题目描述
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 如果 可以变为 1,那么这个数就是快乐数。 如果 n 是快乐数就返回 true ;不是,则返回 false 。
二、解题思路
这道题我一开始看,真没和链表联系在一起来,老师讲解后,才明白。 我们求每一个数的每个数字的平方和,就可以把这个数和它每个位置平方和这个数联系起来,从而形成链表般的结构,这样我们就可以如上面141题的思路判断是否是环形链表来做题了。
1.如果这个数字如题中说的最终无限循环,始终不到一,那么两个指针会相遇,所以它就是个环形链表。我们可以结束遍历,同时判定出该数字不是快乐数。
2.如果遍历过程中指针指向了数字1,那么就可以得出结论,该数字是快乐数。
代码如下:
/**
* @param {number} n
* @return {boolean}
*/
var isHappy = function(n) {
if(n === 1) return true
let p = getnext(n),q = getnext(getnext(n))
while(q!=p && q!= 1){
p = getnext(p)
q = getnext(getnext(q))
}
// 循环结束是因为无限循环导致指针相遇的话,q != 1,返回false
// 如果是因为出现了1,那么返回true
return q === 1
};
function getnext(num){ // 求下一个数字 & 下一个链表节点
let z = 0
while(num){
z += ((num%10)*(num%10))
num = Math.floor(num/10)
}
return z
}
总结
其实这个链表结构,在JS中也不是很陌生的东西,JS的原型链,就是这种类似的结构,懂原型链的话,就很容易理解。对象中的一个属性作为指针,指向另一个对象,即给这个属性赋上另一个引用类型的对象,这样就是一个链表了
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情