牛客网剑指offer66道题(JS实现,部分题目含思路及拓展方法,持续更新)

【题1】二维数组中的查找

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

思路:(1)矩阵是有序的,从左向右递增,从上向下递减;

           (2)从左下角开始查找,比目标值大的,向上找;比目标值小的,向右找。

function Find(target, array)
{
    let rows = array.length;
    let columns = array[0].length;
    for (var j = 0, i = rows - 1; i  >= 0 && j < columns;) {
        if (array[i][j] == target) {
            return true
        } else if (array[i][j] > target) {
            i--;
            continue
        } else if (array[i][j] < target) {
            j++
            continue
        }
    }
    return false
}

【题2】替换空格

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

function replaceSpace(str)
{
    // 首先将字符串转换为数组["We", "Are", "Happy"]
    let array = str.split(' ')
    for (var i = 0; i < array.length - 1; i++) {
        // 将%20添加进去["We%20", "Are%20", "Happy"]
        array[i] = array[i] + "%20" 
    }
    // 数组转换为字符串
    let arr = array.join('')
    return arr
}

牵扯到一个问题,使用正则表达式将逗号删除

function replaceSpace(str)
{
    // 首先将字符串转换为数组["We", "Are", "Happy"]
    let array = str.split(' ')
    for (var i = 0; i < array.length - 1; i++) {
        // 将%20添加进去["We%20", "Are%20", "Happy"]
        array[i] = array[i] + "%20," 
    }
    // 数组转换为字符串
    let arr = array.join('')
    // 由于字符串中带了逗号We%20,Are%20,Happy,使用正则表达式将逗号删除We%20Are%20Happy
    array = arr.replace(/^,/g,'')
    return array
}

其他人的好的方式

// \s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
// 直接遍历字符串,遇到空格就替换。
return str.replace(/\s/g,'%20')


return str.split(" ").join("%20")

【题3】从尾到头打印链表

输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。

/*function ListNode(x){
    this.val = x;
    this.next = null;
}*/
function printListFromTailToHead(head)
{
    let array = []
    let start = head
    while(start) {
        array.push(start.val)
        start = start.next
    }
    return array.reverse()
}

【题4】计算1+2+3+…………+n

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

基于此,采用短路求值原理:

“||”运算符表示或,有一个为真则结果为真,前半部分判断出为真之后,不用继续考虑后半部分,最终结果为真;

“&&”运算符表示与,有一个为假则结果为假,前半部分判断出为假之后,不用考虑后半部分,最终结果为假。

利用上述原理,可以进行递归运算。

function Sum_Solution(n)
{
    var ans = n
    ans && (ans += Sum_Solution(n-1))
    return ans
}

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

  1. 两个数异或:相当于每一位相加,而不考虑进位;
  2. 两个数相与,并左移一位:相当于求得进位;
  3. 将上述两步的结果相加
function Add(num1, num2)
{
    while(num2 != 0) {
        var sum = num1 ^ num2 // 两数相加,不考虑进位
        var num3 = (num1&num2) << 1 // 进位
        num1 = sum
        num2 = num3
    }
    return num1
}

13+11 = ?; 

13 的二进制      1 1 0 1                     -----a        13 

11 的二进制      1 0 1 1                     -----b        11   

 

 (a&b)<<1  ->  1 0 0 1 0                   -----d         18

          a^b  ->     0 1 1 0                   -----e          6 

 

 (d&e)<<1  ->  0 0 1 0 0                  ------f         4

          d^e  ->  1 0 1 0 0                  -----g        20

 

 (f&g)<<1  ->  0 10 0 0                  ------h        8

          f^g  ->  1 0 0 0 0                  ------i          16

 

 (h&i)<<1  ->  0 0 0 0 0                  ------h        0       ------------退出循环

          h^i  ->  1 1 0 0 0                 ------i          24

【题6】输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

function NumberOf1(n)
{
    //js中负数使用二进制补码的形式存储
    if (n<0) {
        //无符号右移将负数的二进制码当成正数的二进制码
        n = n >>> 0
    }
    // n.toString(2)转化成二进制数,n.toString(2).split('1'),n为16打印结果["", "00000"]
    var arrN = n.toString(2).split('1')
    return arrN.length-1
}

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

function duplicate(numbers, duplication)
{
    //这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
    //函数返回True/False
    if (numbers.length === 0 || numbers.length ===1) {
        return false
    }
    for (var i = 0; i < numbers.length -1; i++) {
        for (var j = numbers.length-1; j > i; j--) {
            if (numbers[i] === numbers[j]) {
                dupli
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Delicia_Lani

你的鼓励将是我写作的动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值