剑指offer算法篇(javascript)(下)number[41-67]

本文详细解析了41至67道算法题目,涵盖了数组、字符串、链表、二叉树等多个主题,旨在提升JavaScript编程中的算法能力。内容包括连续正数序列求和、数字匹配、字符串操作、扑克牌顺子判断、链表环的检测与删除、二叉树的各种操作等。通过实例解析,帮助读者掌握各种算法技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

四十一、和为S的连续正数序列

题目描述
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!
输出描述:
输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序

function FindContinuousSequence(sum)
{
    // write code here
    if(sum<2) return []
    let a=1,
        b=2,
        c=3,//最小为3
        result = []
    while(a<=Math.floor(sum/2)){
        if(c<sum) {
            b++//先b++因为已经确定sum不是3所以b肯定要先加1
            c += b
            
        }
        else if(c>sum) {
            c -= a
            a++//a和后面全部后加加是因为要从1开始一个个按顺序排除
        }
        else{
            let arr = []
            for(let i=a;i<=b;i++) {
                arr.push(i)
            }
            result.push(arr)
            if(a+1<b) {
                c -= a
                a++
            }
            else{
                break
            }
        }
    }
    return result
}
四十二、和为S的两个数字

题目描述
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
输出描述:
对应每个测试案例,输出两个数,小的先输出。

function FindNumbersWithSum(array, sum)
{
    // write code here
    let num
    for(let i =0;i<array.length-1&&array[i]<sum/2;i++) {
        num = array.indexOf(sum-array[i], i+1)
        if(num != -1) return [array[i],array[num]]
    }
    return []
}
四十三、左旋转字符串

题目描述
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!

function LeftRotateString(str, n)
{
    // write code here
    if(str==null||str.length==0){
        return "";
    }
    n=n%str.length;
    return str.slice(n)+str.slice(0,n);   
}
四十四、翻转单词顺序序列

题目描述
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

function ReverseSentence(str)
{
    // write code here
    return str.split(" ").reverse().join(" ")
}
四十五、扑克牌顺子

题目描述
LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。

function IsContinuous(numbers)
{
    // write code here
    //必须满足两个条件
//1. 除0外没有重复的数
//2. max - min < 5,当然0没在max和min其中
    let arr = []
    for(let i=0;i<14;i++) {
        arr.push(0)
    }
    if(numbers.length != 5) return false
    let max = -1,
        min = 14
    for(let i=0;i<numbers.length;i++) {
        arr[numbers[i]]++
        if(numbers[i] == 0) continue
        if(arr[numbers[i]] > 1) return false
        if(numbers[i] > max) max = numbers[i]
        if(numbers[i] < min) min = numbers[i]
    }
    return max-min<5
}
四十六、孩子们的游戏(圈圈中最后剩下的数)

题目描述
每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数…这样下去…直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!_)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)

如果没有小朋友,请返回-1

function LastRemaining_Solution(n, m)
{
    // write code here
    if(n == 0){
        return -1
    }
    if(n == 1){
        return 0
    }else{
        return (LastRemaining_Solution(n-1, m) + m) % n
    }
}
四十七、求1+2+3+…+n

求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

function Sum_Solution(n)
{
    // write code here
    return n*(n+1)/2
}
四十八、不用加减乘除做加法

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

function Add(num1, num2)
{
    // write code here
    if(num2 === 0) {
        return num1;
    }
    return Add(num1 ^ num2, (num1 & num2) << 1)
}
四十九、把字符串转化为整数

题目描述
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
输入描述:
输入一个字符串,包括数字字母符号,可以为空
输出描述:
如果是合法的数值表达则返回该数字,否则返回0
示例1
输入
+2147483647
1a33
输出
2147483647
0

function StrToInt(str)
{
    // write code here
    //1.
    //parseInt() 函数可解析一个字符串,并返回一个整数。
    //return Number(str) ? parseInt(str) : 0
    
    //2.
    //let result = str-0
    //if(result!==result){
    //    return 0
    //}
    //return result
    
    //3.
    let len = str.length,
        flag = 1,
        res = 0;
    if (!len || typeof str != "string") {
        return 0;
    }
    // 负数的处理
    if (str[0] === '-') {
        flag = -1;
    }
    // 前面有符号从i=1开始,没有从0开始
    let index = (str[0] === '-' || str[0] === '+') ? 1 : 0
    for (let i = index; i < len; i++) {
        // 如果当前位不在0-9范围
        if (!(str[i] >= '0' && str[i] <= '9')) {
            return 0;
        }
        //每次乘以10,-0转换成数字类型
        // res = res * 10 + (str[i] - '0');
        res = res * 10 + parseInt(str[i]) // 1  12  123
    }
    return res * flag;

}
五十、数组中重复的数字

题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

function duplicate(numbers, duplication)
{
    // write code here
    //这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
    //函数返回True/False
    if(numbers.length <= 1) return false
    for(let i=0;i<numbers.length-1;i++) {
        for(let j=numbers.length-1;j>i;j--) {
            if(numbers[i]===numbers[j]) {
                duplication[0] = numbers[i]
                return true
            }
        }
    }
    return false
}
五十一、构建乘积数组

题目描述
给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]。不能使用除法。

思路:B[i]的值可以看作下图的矩阵中每行的乘积。
下三角用连乘可以很容求得,上三角,从下向上也是连乘。
因此我们的思路就很清晰了,先算下三角中的连乘,即我们先算出B[i]中的一部分,然后倒过来按上三角中的分布规律,把另一部分也乘进去。
在这里插入图片描述

function multiply(array)
{
    // write code here
    if(!array.length) return false
    let arr = []
    for(let i=0;i<array.length;i++) {
        arr[i] = 1
        for(let j=0;j<array.length;j++) {
            if(i != j) {
                arr[i] *= array[j]
            }
        }
    }
    return arr
}
五十二、正则表达式匹配

题目描述
请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配

个人理解:‘.’前字符表示了任一字符并且占用一个符号位,‘*’前字符表示没出现过,并且可出现任意次。

//s, pattern都是字符串
function match(s, pattern)
{
    let reg=new RegExp("^" + pattern + "$");
    return reg.test(s);
}
五十三、表示数值的字符串

题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。 但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。

//s字符串
function isNumeric(s)
{
    // write code here
     return !isNaN(Number(s))
}
五十四、字符流中第一个不重复的字符

题目描述
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
输出描述:
如果当前字符流没有存在出现一次的字符,返回#字符。

//Init module if you need
let map = {}
function Init()
{
    // write code here
    map = {}
}
//Insert one char from stringstream
function Insert(ch)
{
    // write code here
    map[ch] = map[ch] ? map[ch]+1 : 1
}
//return the first appearence once char in current stringstream
function FirstAppearingOnce()
{
    // write code here
    for(const i in map) {
        if(map[i] === 1) 
            return i
    }
    return "#"
}
五十五、链表中环的入口结点

题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路:设置快慢指针,都从链表头出发,快指针每次走两步,慢指针一次走一步,假如有环,一定相遇于环中某点(结论1)。接着让两个指针分别从相遇点和链表头出发,两者都改为每次走一步,最终相遇于环入口(结论2)。以下是两个结论证明:
两个结论:
1、设置快慢指针,假如有环,他们最后一定相遇。
2、两个指针分别从链表头和相遇点继续出发,每次走一步,最后一定相遇与环入口。
证明结论1:设置快慢指针fast和low,fast每次走两步,low每次走一步。假如有环,两者一定会相遇(因为low一旦进环,可看作fast在后面追赶low的过程,每次两者都接近一步,最后一定能追上)。
证明结论2:
设:
链表头到环入口长度为–a
环入口到相遇点长度为–b
相遇点到环入口长度为–c
在这里插入图片描述
则:相遇时
快指针路程=a+(b+c)k+b ,k>=1 其中b+c为环的长度,k为绕环的圈数(k>=1,即最少一圈,不能是0圈,不然和慢指针走的一样长,矛盾)。
慢指针路程=a+b
快指针走的路程是慢指针的两倍,所以:
(a+b)*2=a+(b+c)k+b
化简可得:
a=(k-1)(b+c)+c 这个式子的意思是: 链表头到环入口的距离=相遇点到环入口的距离+(k-1)圈环长度。其中k>=1,所以k-1>=0圈。所以两个指针分别从链表头和相遇点出发,最后一定相遇于环入口。

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
//1、设置快慢指针,假如有环,他们最后一定相遇。
//2、两个指针分别从链表头和相遇点继续出发,每次走一步,最后一定相遇与环入口。
function EntryNodeOfLoop(pHead)
{
    // write code here
    if(pHead == null || pHead.next == null) return null
    let pHead1 = pHead,
        pHead2 = pHead,
        flag = true
    while(flag) {
        pHead1 = pHead1.next
        pHead2 = pHead2.next.next
        if(pHead1 == pHead2) {
            flag = false
        }
    }
    pHead2 = pHead
    flag = true
    while(flag) {
        if(pHead1 == pHead2) return pHead1
        else {
            pHead1 = pHead1.next
            pHead2 = pHead2.next
        }
    }
}
五十六、删除链表中重复的结点

题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function deleteDuplication(pHead)
{
    // write code here
    var newHead = new ListNode('head');
    newHead.next = pHead;
    var pHead = newHead;
    var qHead = pHead.next;
    while(qHead) {
        while((qHead.next!=null) && (qHead.val == qHead.next.val)) {
            qHead = qHead.next;
        }
        //没移动
        if(pHead.next == qHead) {
            pHead = qHead;
            qHead = qHead.next;
             
        }
        //移动了
        else {
            qHead = qHead.next;
            pHead.next = qHead;//这里才是真正改变了链表的结构和最后输出
        }
         
    }
    return newHead.next;
     
}

五十七、二叉树的下一个结点

题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

注意:分析二叉树的下一个节点,一共有以下情况:
1.二叉树为空,则返回空;
2.节点右孩子存在,则设置一个指针从该节点的右孩子出发,一直沿着指向左子结点的指针找到的叶子节点即为下一个节点;
3.节点不是根节点。如果该节点是其父节点的左孩子,则返回父节点;否则继续向上遍历其父节点的父节点,重复之前的判断,返回结果。

/*function TreeLinkNode(x){
    this.val = x;
    this.left = null;
    this.right = null;
    this.next = null;
}*/
function GetNext(pNode)
{
    // write code here
    if(!pNode) return null
    let p = null
    if(pNode.right) {  // 存在右子树
        p = pNode.right
        while(p.left) {
            p = p.left
        }
    }
    else { // 不存在右子树
        //next表示父节点
        p = pNode.next
        if(pNode.next&&pNode.next.right == pNode) {
            while(p.next&&p.next.right == p){//重复上级for循环的判断
                p = p.next
            }
            if(p.next == null){
                p = null
            } 
            else {
                p = p.next
            }
        }
    }
    return p
}
五十八、对称的二叉树

题目描述
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */
function isSymmetrical(pRoot)
{
    // write code here
    return compared(pRoot, pRoot)
}
function compared(p1, p2) {
    if(p1==null && p1==null) return true
    if(p1==null || p2 == null) return false
    if(p1.val!=p2.val) return false
    return compared(p1.left, p2.right) && compared(p1.right, p2.left)
}
五十九、按之字形顺序打印二叉树

题目描述
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */
function Print(pRoot)
{
    if(!pRoot){
        return [];
    }
    var queue = [],
        result = [],
        flag=true;
    queue.push(pRoot);
    while(queue.length){
        var len = queue.length;
        var tempArr = [];
        for(var i = 0;i<len;i++){
            var temp = queue.shift();
            tempArr.push(temp.val);
            if(temp.left){
                queue.push(temp.left);
            }
            if(temp.right){
                queue.push(temp.right);
            }
        }
        if(!flag){
            tempArr.reverse();
        }
        flag = !flag;
        result.push(tempArr);
    }
    return result;
}

六十、把二叉树打印成多行

题目描述
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */
function Print(pRoot)
{
    if(!pRoot){
        return [];
    }
    var queue = [],
        result = [];
    queue.push(pRoot);
    while(queue.length){
        var len = queue.length;
        var tempArr = [];
        for(var i = 0;i<len;i++){
            var temp = queue.shift();
            tempArr.push(temp.val);
            if(temp.left){
                queue.push(temp.left);
            }
            if(temp.right){
                queue.push(temp.right);
            }
        }
        result.push(tempArr);
    }
    return result;
}

六十一、序列化二叉树

题目描述
请实现两个函数,分别用来序列化和反序列化二叉树

二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。

二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
}
var arr = [];
function Serialize(pRoot)
{
    // write code here
    if(pRoot==null){
        arr.push('a');
    }else{
        arr.push(pRoot.val);
        Serialize(pRoot.left);
        Serialize(pRoot.right);
    }
        
}
function Deserialize(s)
{
    // write code here
    var node = null;
    if(arr.length<1){
        return null;
    }
    var number = arr.shift();
    if(typeof number == 'number'){
        node = new TreeNode(number);
        node.left = Deserialize(arr);
        node.right = Deserialize(arr);
    }
    return node;
}

六十二、二叉搜索树的第k个节点

题目描述
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。

/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */
//二叉搜索树左中右按顺序大小排列
function KthNode(pRoot, k)
{
    // write code here
    if(!pRoot) return
    let arr = []
    arrangement(pRoot, arr)
    return arr[k-1]
}
function arrangement(pRoot, arr) {
    if(!pRoot) return
    arrangement(pRoot.left, arr)
    arr.push(pRoot)
    arrangement(pRoot.right, arr)
}
六十三、数据流中的中位数

题目描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

let arr = [];
function Insert(num)
{
    let len = arr.length;
    if(len === 0)
        arr.push(num);
    else {
        let i = len-1;
        while(i >= 0 && arr[i] > num) {
            arr[i+1] = arr[i];
            i--;
        }
        arr[i+1] = num;
    }
}
function GetMedian(){
    let len = arr.length;
    // odd
    if(len % 2 != 0){
        return arr[Math.floor(len/2)];
    } else{
        return (arr[len/2-1]+arr[len/2])/2
    }
}

六十四、滑动窗口最大值

题目描述
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

function maxInWindows(num, size)
{
    if(size > num.length || size === 0)
        return []
    var res = [], maxIndex = -1
    for(var l = 0, r = size-1;r < num.length;l++, r++){
        if(maxIndex < l){
            maxIndex = getMaxIndex(num, l, r)
        }
        if(num[r] > num[maxIndex]){
            maxIndex = r
        }
        res.push(num[maxIndex])
    }
    return res
}
function getMaxIndex(num, l, r){
    var index = l
    for(var i = l;i <= r;i++) {
        if(num[i] > num[index])
            index = i
    }
    return index
}
六十五、矩阵中的路径

在这里插入图片描述
回溯
基本思想:
0.根据给定数组,初始化一个标志位数组,初始化为false,表示未走过,true表示已经走过,不能走第二次
1.根据行数和列数,遍历数组,先找到一个与str字符串的第一个元素相匹配的矩阵元素,进入judge
2.根据i和j先确定一维数组的位置,因为给定的matrix是一个一维数组
3.确定递归终止条件:越界,当前找到的矩阵值不等于数组对应位置的值,已经走过的,这三类情况,都直接false,说明这条路不通
4.若k,就是待判定的字符串str的索引已经判断到了最后一位,此时说明是匹配成功的
5.下面就是本题的精髓,递归不断地寻找周围四个格子是否符合条件,只要有一个格子符合条件,就继续再找这个符合条件的格子的四周是否存在符合条件的格子,直到k到达末尾或者不满足递归条件就停止。
6.走到这一步,说明本次是不成功的,我们要还原一下标志位数组index处的标志位,进入下一轮的判断。

function hasPath(matrix, rows, cols, path)
{
    // write code here
    if(path.length == 0) return true
    if(rows*cols < path) return false
    let status = new Array(rows*cols)
    status.fill(0)
    for(var i = 0;i < rows;i++){
        for(var j=0;j< cols;j++){
            //循环遍历二维数组,找到起点等于path第一个元素的值,再递归判断四周是否有符合条件的----回溯法
            if(findPath(matrix,rows,cols,i,j,path,0,status)){
                return true
            }
        }
    }
    return false
}
function findPath(matrx,rows,cols,i,j,path,pathl,status) {
     if(i<0 || j<0 || i>=rows || j>=cols || matrx[i*cols+j] !== path[pathl] || status[i*cols+j]){
        return false
    }
    if(pathl === path.length-1){
        return true
    }
    status[i*cols+j] = true
    if(
        findPath(matrx,rows,cols,i+1,j,path,pathl+1,status)||
        findPath(matrx,rows,cols,i-1,j,path,pathl+1,status) ||
        findPath(matrx,rows,cols,i,j+1,path,pathl+1,status) ||
        findPath(matrx,rows,cols,i,j-1,path,pathl+1,status)
    ){
        return true
    }
    status[i*cols+j] = false
    return false
}
六十六、机器人运动范围

题目描述
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?

function movingCount(threshold, rows, cols) {
      var visited = [];
      for (var i = 0; i < rows; i++) {
        visited.push([]);
        for (var j = 0; j < cols; j++) {
          visited[i][j] = false;
        }
      }
      return moveCount(threshold, rows, cols, 0, 0, visited);
    }
 
    function moveCount(threshold, rows, cols, row, col, visited) {
      if (row < 0 || row == rows || col < 0 || col == cols || visited[row][col]) {
        return 0;
      }
      var sum = 0;
      var temp = row + "" + col;
      for (var i = 0; i < temp.length; i++) {
        sum += temp.charAt(i) / 1;
      }
      if (sum > threshold) {
        return 0
      }
      visited[row][col] = true;
      return 1 + moveCount(threshold, rows, cols, row, col - 1, visited) +
        moveCount(threshold, rows, cols, row, col + 1, visited) +
        moveCount(threshold, rows, cols, row - 1, col, visited) +
        moveCount(threshold, rows, cols, row + 1, col, visited);
    }

六十七、剪绳子

题目描述
给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]xk[1]x…xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
输入描述:
输入一个数n,意义见题面。(2 <= n <= 60)
输出描述:
输出答案。
示例1
输入
8
输出
18

function cutRope(number)
{
    // write code here
    let result = [];
    let answer = [0, 0, 1, 2, 4];
    if(number < 5) {
        return answer[number];
    }
    while(number > 0) {
        if(number - 3 >= 0) {
            result.push(3);
            number -= 3;
        }
        if(number - 2 >= 0) {
            result.push(2);
            number -= 2;
        }
    }
    return result.reduce((x, y) => x * y);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值