剑指offer js 其中10题

11.(进制位运算)输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

function NumberOf1(n)
{
    // write code here
    var count = 0;
    while(n!= 0){
        count++;
        n = n & (n - 1);  //位运算&直接讲n转换成了二进制
    }
    return count;
}

12.(正负数循环)给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0
(js是弱类型语言,没有double、int之分)

function Power(base, exponent)
{
    // write code here
    if(base===0)
        return false;
    if(exponent ===0)
        return 1;
    var x=1;
    if(exponent>0){
        for(let i=0;i<exponent;i++){
            x=x*base;
        }
        return x;
    }
    else{
        for(let i=0;i>exponent;i--){
            x=x/base;
        }
        return x;
    }
}

13.(数组)输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
(暴力解法,新建一个空数组,先把技奇数的push进去,再把偶数push进去)

var exchange = function(nums) {
    var arrB=[];
    var len=nums.length;
    var j=0;
    for(let i=0;i<nums.length;i++){
        if(nums[i]%2===1){
            arrB.push(nums[i])
        }
    }
    for(let i=0;i<nums.length;i++){
        if(nums[i]%2===0){
            arrB.push(nums[i])
        }
    }
    return arrB
};

14.(链表)输入一个链表,输出该链表中倒数第k个结点。

var getKthFromEnd = function(head, k) {
var p=head;
    var q=head;
    while(k>0){
        p=p.next;
        k--;
    }
    while(p){
        p=p.next;
        q=q.next;
    }
    return q
};

15.(数组最小值Math.min.apply(Math,arr))输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

var getLeastNumbers = function(arr, k) {
    var arr1=[];
    if(k===0){
        return [];
    }
    if(k>=arr.length){
        return arr;
    }
    for(let i=0;i<k;i++){
        let _min=Math.min.apply(Math,arr);   //获取数组中的最小值
        let _index=arr.indexOf(_min);   //最小值的索引
        arr1.push(_min);    //输入arr1
        arr.splice(_index,1)  
    }
    return arr1;
};

15.(数组重复数字)在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
方法一:双循环(时间复杂度高)

var findRepeatNumber = function(nums) {
    let len=nums.length;
    for(let i=0;i<len;i++){
        let c=nums[i];
        for(let j=i+1;j<len;j++){
            if(c===nums[j]){
                return c;
            }
        }
    }
return null;
};
/* 法二:数组排完序后,相等的数就会相邻。  此方法最好
     于是循环直接比较就好,遇到相等的就返回该值。*/
    nums.sort();
    for(var i=0;i<nums.length-1;i++){
        if(nums[i]==nums[i+1]) return nums[i];
    }
return null;
//方法三:使用Set(),自动忽略重复元素,若长度不增加,说明此番输入的是重复元素
let _set=new Set();
    for(var i in nums){
        let _len=_set.size;
        _set.add(nums[i]);
        if(_len===_set.size)
        return nums[i];
    }
    return null;
}

16.(链表,数组倒序arr.reverse())输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

var reversePrint = function(head) {
    //依次输入head.val,再倒序
    var arr=[];  
    while(head){
        arr.push(head.val);
        head=head.next;
    }
    return(arr.reverse())
};
//方法二:栈实现
var res = []
    while(head) {
        res.unshift(head.val) 
//unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。
        head = head.next
    }
    return res

17.(字符串重复)请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

var lengthOfLongestSubstring = function(s) {
    var s1='';
    var maxlen=0;
    for(let i=0;i<s.length;i++){
         if(s1.indexOf(s[i]) != -1){  //找到有重复字符
            s1 = s1.slice(s1.indexOf(s[i]) + 1);
            s1 += s[i];
         }
         else{
            s1=s1+s[i];
            maxlen = Math.max(maxlen, s1.length);
            
         }
    }
    return maxlen;
};

18.(number转string)请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。

var hammingWeight = function(n) {
    //正则方法
    const r =  n.toString(2).match(/1/g);  //将1的都提出来放入字符串r种
    return r ? r.length : 0;
    //普通方法
    // var str=n.toString(2);
    // var flag=0;
    // for(let i=0;i<str.length;i++){
    //     if(str[i]==='1'){
    //         flag+=1;
    //     }
    // }
    // return flag;
};

18.(幂次方math.pow(x,y))输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。

var printNumbers = function(n) {
    var nums=[];  
    if(n<1){
        return nums;
    }
    // var flag=1;
    // for(let i=0;i<n;i++){
    //     flag=flag*10;   //10^n
    // }
    var flag=Math.pow(10,n);  //用时与上述暴力方法差不多
    for(let i=1;i<flag;i++){
        nums.push(i);
    }
    return nums;
};

19.(删除节点)给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。

var deleteNode = function(head, val) {
    if(head.val===val){
        return head.next;
    }
    var p=head;
    var q=head;
    while(p){
        if(p.val===val){
            q.next=p.next;
            break;
        }
        q=p;
        p=p.next;
    }
    return head;
     //有一个很好的思路,在head前面加入一个哨兵节点pre,则只需要一个指针就能遍历
};

20.(数组累乘)给定一个数组 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]。不能使用除法。

var constructArr = function(a) {
    //a[i]的左边和右边分别累乘,首尾两位设置为1,
    //在第二个循环中对应相乘就可以了
    var len=a.length;
    if(len===0){
        return [];
    }
    var b=[];
    b[0]=1;
    var c=[];
    c[len-1]=1;
    for(let i=1;i<len;i++){
        b[i]=b[i-1]*a[i-1];
        c[len-1-i]=c[len-i]*a[len-i];
    }
    for(let i=0;i<len;i++){
        b[i]=b[i]*c[i];
    }
    return b;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值