I am getting RangeError: Maximum call stack size exceeded error in Javascript

I am getting RangeError: Maximum call stack size exceeded error in Javascript

我正在尝试通过递归解决 leetcode 的问题,但我收到一条错误消息说 RangeError: Maximum call stack size exceeded 也许我做错了什么。

问题:

编写一个算法来确定数字 n 是否快乐。

快乐号码是由以下过程定义的号码:

从任何正整数开始,将数字替换为其数字的平方和。

重复这个过程直到数字等于1(它会停留在那里),或者它在一个不包括1的循环中无限循环。 此过程以 1 结尾的那些数字是快乐的。

Return 如果 n 是一个快乐的数字,则为真,否则为 false


Example 1:

Input: n = 19
Output: true
Explanation:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
Example 2:

Input: n = 2
Output: false

我的代码:

var isHappy = function(n) {
    if(n.length<2) return false
    
    
    var fn=(n)=>{
        let i=0; 
        let sum=0;
    while(i<n.length){
     sum=sum+Math.pow(n[n.length-1-i],2);
     i++;   
    }
    while(sum!==1){
     //console.log(sum)
    fn(sum);
    }
 if(sum === 1) return true
    }
    fn(n)
};

PS: 我不需要这个问题的解决方案。我想找出为什么我的代码不起作用以及我做错了什么。而且,我应该做哪些更改才能正常工作。

Link到上面的问题

Maximum call stack size exceeded

当函数调用其他函数的次数过多时会出现此错误。在这种情况下,如果数字是一个“不快乐”的数字,您的函数将无休止地递归调用自身。

考虑在你的函数中添加一些东西,让你知道进程是否无限循环。

考虑使用 arguments/arrays 来存储已经出现的数字。

正如您自己所写,“重复该过程,直到数字等于 1(它将停留在该位置),或者它无限循环 一个循环”。 =34=].

在您的实现中,fn 无限调用自身。在此过程中,javascript 虚拟机在每次迭代时都会在内存中创建一个函数上下文。这可以在特定时间完成,之后错误 Maximum call stack size exceeded 抛出。

我做错了什么?

当你找到一个快乐的数字时,你 return 为真,否则你永远不会 return 为假。添加一个条件来检测不满意的数字(检测一个循环),在这种情况下 return false。

编辑:这是一个示例实现:

var isHappy = function(n) {
    if(n.length<2) return false
    
    // placeholder to store already called values
    const calledValues= new Set()
    
    var fn=(n)=>{
        let i=0; 
        let sum=0;
        
      if (calledValues.has(n))
        // cycle detected!
        return false;
      
      calledValues.add(n);
      
      while(i<n.length){
        sum=sum+Math.pow(n[n.length-1-i],2);
        i++;   
      }
 
      if (sum !== 1)
        return fn(sum.toString());
      else
        // sum === 1, number is happy!
        return true
    }
    
    // make sure to pass a string to fn
    return fn(n.toString());
};

(new Array(20)).fill().map((_,i)=>10+i)
.forEach(n=> console.log(n, "is happy?", isHappy(n)));