[路飞] 快乐数,反转列表II算法解析

199 阅读2分钟

一.快乐数解析

「快乐数」定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。

然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。

如果 可以变为  1,那么这个数就是快乐数。

实例:

11 + 99 = 82

88 + 22 = 68

66 + 88 = 100

11 + 00 + 0*0 = 1

```

将计算过程排列就 19 82 68 100 1 null 可以将这个数字当做链表判环来处理,没有坏且等于1就是快乐数,因为如果有相等的节点就会陷入死循环,所以该处理逻辑就是链表判环逻辑.

代码实现过程

var getNext = function(x){

let z = 0;

当x时两位数时会执行联系平方相加,当x大于100时会三字相加每次x%10都是取个位数.

while(x){

z += (x % 10) * (x % 10);//

x = parseInt(x / 10);

}

return z;

}

var isHappy = function(n) {

//定义头结点p,定义头结点的下一个节点q,p每次走一步,q每次走两步

let p = getNext(n),q = getNext(getNext(n));

//当p不等于q说明该链表没有环,当q等于1时说明是快乐数.

while(p != q && q != 1){

p = getNext(p);

q = getNext(getNext(q));

}

return q == 1;

};

二.反转列表II

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

示例 1:

示例 1:

输入:head = [1,2,3,4,5], left = 2, right = 4

输出:[1,4,3,2,5]

示例 2:

输入:head = [5], left = 1, right = 1

输出:[5]

解析:上一篇文章介绍了第一种链表反转,这次的链表是反转链表一部分,因为假如我们从第一个节点开始反转,我们需要一个虚拟头结点,此时虚拟节点就是头结点为空的新节点,

var reverseBetween = function(head, left, right) {

if(!head || !head.next) return head;

//顶一个虚节点pre,从第一个节点开始判断,定义一个p = pre,

let pre = new ListNode(0,head),p = pre,cnt = right - left + 1;

//开始虚幻让不需要反转的前部分节点等于p,然后将剩下的节点通过方法反转,

while(-- left) p = p.next;

//此时p就是反转前的节点,reverseN(p.next,cnt)反转后的节点

p.next = reverseN(p.next,cnt);

return pre.next;

};

var reverseN = function(head,n){

if(!head || !head.next || n == 1) return head;

tail 头结点的下一个节点,

let tail = head.next,p = reverseN(head.next,n -1)

head.next = tail.next;

tail.next = head;

return p;

}