剑指offer

本文提供了一系列剑指Offer上的经典算法题解答,包括求1到n中所有1的出现次数、找出数组最小排列组合、查找第index个丑数等,并详细展示了每道题目的解题思路与代码实现。

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

求1到n的数中出现的所有1的次数
打印出数组元素排列组合中最小的组合
找到第index个丑数
第一个只出现一次的字符位置
归并排序
二叉树的深度
判断平衡二叉树
数组中只出现一次的数字
和为s的连续正数序列
左旋转字符串
翻转单词顺序列
(主要是同步存一些剑指offer上的题目,前面这些是很早写的,后期有时间会补上思路)


求1到n的数中出现的所有1的次数

//求1到n的数中出现的所有1的次数
        console.log(NumberOf1Between1AndN_Solution(1));
            function NumberOf1Between1AndN_Solution(n)
        {
            var sum=0;
            if(n<1){
                return sum;
            }
            if(n>=1 && n<10) return 1;
            var strN=n.toString();
            var lenN=strN.length;
            for(let i=0;i<lenN;i++){
                let firstStr = strN.substring(i,i+1);
                if(firstStr == '1'){
                    let restStr = (i+1==lenN)?'0' : strN.substring(i+1);
                    sum = sum + parseInt(restStr) +1;
                    sum = sum + assistNumber(strN,lenN,i,firstStr);
                }else if(firstStr == '0'){
                    continue;
                }
                else{
                    sum = sum +assistNumber(strN,lenN,i,firstStr);
                }
            }
            console.log(sum);
        }
        function assistNumber(strN,lenN,i,firstStr) {  
            if(i+1 == lenN){
                return 1;
            }
            let bits=lenN - i;
            let sum = 0;
            let firNum=parseInt(firstStr);
            //排列组合
            for(let i =0 ;i<bits ;i++){
                let mul = firNum;
                if(i+1 == bits){
                    if(firNum == '1'){
                        mul =0;
                    }else  {
                        mul = Math.pow(10,bits-1);
                    }
                }else{
                    mul = firNum * Math.pow(10,bits-2);
                }
                sum = sum +mul;
            }
            return sum;
        }

打印出数组元素排列组合中最小的组合

        //打印出数组元素排列组合中最小的组合
        //console.log(PrintMinNumber([3,32,321]));
        function PrintMinNumber(numbers)
        {
            if(numbers.length<1){
                return "";
            }
            let arr = assistPrintMinNumber(numbers);
            return arr.join("") ;
        }
        
        function assistPrintMinNumber(numbers){
            if(numbers.length <= 1){
                return numbers;
            }
            var priot = numbers.splice(0,1);
            var left = [],right = [];
            for(let i=0 ; i<numbers.length ; i++){
                let concatStr1 = priot.toString() + numbers[i].toString();
                let concatStr2 = numbers[i].toString() + priot.toString();
                if(concatStr1 < concatStr2){
                    right.push(numbers[i]);
                }else{
                    left.push(numbers[i]);
                }
            }
            return assistPrintMinNumber(left).concat(priot,assistPrintMinNumber(right));
        }

找到第index个丑数

        //找到第index个丑数
        function GetUglyNumber_Solution(index)
        {
            if(index<7){
                return index;
            }
            let uglyNum = [];
            let count2 = 0,
                count3 = 0,
                count5 = 0;
            uglyNum[0] = 1;
            for(let i=1 ;i<index ;i++){
                uglyNum[i] = Math.min(uglyNum[count2]*2,uglyNum[count3]*3,uglyNum[count5]*5);
                if(uglyNum[i] == uglyNum[count2]*2)  count2++;
                if(uglyNum[i] == uglyNum[count3]*3)  count3++;
                if(uglyNum[i] == uglyNum[count5]*5)  count5++;
            }
            console.log(uglyNum[index]) ;
        }

第一个只出现一次的字符位置

      //第一个只出现一次的字符位置
      console.log(FirstNotRepeatingChar('google'));
      function FirstNotRepeatingChar(str)
      {
          let charObj = {};
          let len = str.length;
          for(let i=0; i<len; i++){
              if(charObj[str[i]] == undefined){
                  charObj[str[i]] = i;
              }else{
                  charObj[str[i]] = -1;
              }
          }
          for(let i=0; i<len; i++){
              if(charObj[str[i]] >= 0){
                  return i;
              }
          }
          return -1;
      }

归并排序


        //归并排序
        let arr = [10, 3, 1, 5, 11, 2, 0, 6, 3];
        console.log(mergeSort(arr, 0 ,arr.length-1));
        function mergeSort(array,first,end){
            if(first ==end){
                return array;
            }
            let mid = Math.floor((first+end)/2);
            mergeSort(array,first,mid);
            mergeSort(array,mid+1,end);
            array = merge(array,first,mid,end);
            return array;
        }
        function merge(array,first,mid,end){
            let leftStart = first;
            let leftEnd = mid;
            let rightEnd = end;
            let rightStart = mid+1;
            let temp=[];
            let tempIndex = 0;
            while(leftStart<=leftEnd && rightStart<=rightEnd){
                if(array[leftStart] <array[rightStart]){
                    temp[tempIndex++] = array[leftStart++];
                }
                else{
                    temp[tempIndex++] = array[rightStart++];
                }
            }
            while(leftStart<=leftEnd){
                temp[tempIndex++] = array[leftStart++];
            }
            while(rightStart<=rightEnd){
                temp[tempIndex++] = array[rightStart++];
            }
            for(let i=0 ;i<tempIndex ;i++){
                array[first++] = temp[i];
            }
            return array;
        }

二叉树的深度

    //二叉树的深度
    function TreeDepth(pRoot)
    {
        //递归出口
        if(pRoot.left==null && pRoot.right==null){
            return 1;
        }
        let left = 0;
        let right = 0;
        if(pRoot.left){
            left = TreeDepth(pRoot.left);
        }
        if(pRoot.right){
            right = TreeDepth(pRoot.right);
        }
        return left>right?left+1:right+1;
    }

判断平衡二叉树

//判断平衡二叉树
    function IsBalanced_Solution(pRoot)
{
    // write code here
    if(pRoot == null){
        return true;
    }
    let flag = true;
    return IsBalanced_SolutionAssist(pRoot,flag)==false?false:true;
}
function IsBalanced_SolutionAssist(pRoot,flag){
    if(pRoot == null){
        return 0;
    }
    let left = IsBalanced_SolutionAssist(pRoot.left,flag);
    let right = IsBalanced_SolutionAssist(pRoot.right,flag);
    if(left===false || right ===false){
        return false;
    }
    if(Math.abs(left-right)>1){
        return false;
    }
    return Math.max(left+1,right+1);
}

数组中只出现一次的数字

//数组中只出现一次的数字
console.log(FindNumsAppearOnce([3,5,6,4,5,3]));
function FindNumsAppearOnce(array)
{
    //
    let xorRes='' ;
    for(let i=0;i<array.length;i++){
        xorRes ^= array[i];
    }
    xorRes = xorRes.toString(2);
    let priot = xorRes.length - xorRes.lastIndexOf('1');
    let numOneExsist = [],numAnotherExsist = [];
    for(let i=0;i<array.length;i++){
        let temp = array[i].toString(2);
        if(temp[temp.length-priot] == '1'){
            numOneExsist.push(array[i]);
        }else{
            numAnotherExsist.push(array[i]);
        }
    }
    let res = [];
    let xor1 = '';
    let xor2 = '';
    for(let i=0;i<numOneExsist.length;i++){
        xor1 ^=numOneExsist[i];
    }
    for(let i=0;i<numAnotherExsist.length;i++){
        xor2 ^=numAnotherExsist[i];
    }
    res.push(xor1);
    res.push(xor2);
    return res;
}

和为s的连续正数序列

//和为s的连续正数序列
console.log(FindContinuousSequence(100));
function FindContinuousSequence(sum)
{
    let arrayList = [];
    let oneList = [];
    let small = 1;
    let big = 2;
    let listSum = small +big;
    while(small>0 && small<big &&big<= Math.ceil(sum/2)){
        oneList = [];
        if(listSum<sum){
            big++;
            listSum += big;
        }else if(listSum>sum){
            listSum -=small;
            small++;
        }else{
            for(let i=small;i<=big;i++){
                oneList.push(i);
            }
            arrayList.push(oneList);
            big ++;
            listSum +=big;
        }
    }
    return arrayList;
}

和为S的两个数字

//和为S的两个数字
function FindNumbersWithSum(array, sum)
{
    //array是递增数组
    let left = 0;
    let right = array.length-1;
    while(left<right){
        if(array[left]+array[right] <sum){
            left ++;
        }else if(array[left]+array[right] > sum){
            right --;
        }else{
            return [array[left],array[right]];
        }
    }
    return [];
}

左旋转字符串

//左旋转字符串
console.log(LeftRotateString('abcXYZdef',3))
function LeftRotateString(str, n)
{
    let modN = n%str.length;
    console.log(str.substr(modN,));
    console.log(str.substr(0,modN));
    return str.substr(modN,).concat(str.substr(0,modN));
}

翻转单词顺序列

//翻转单词顺序列
console.log(ReverseSentence('student. a am I'));
function ReverseSentence(str)
{
    if(str==null || str==''){
        return '';
    }
    let reverseStr = str.split("").reverse().join("");
    let start =0;
    let spaceIndex =0;
    let tempStr = '';
    spaceIndex = reverseStr.indexOf(" ");
    while(spaceIndex!= -1){
        tempStr += reverseStr.slice(start,spaceIndex).split("").reverse().join("")+" ";
        reverseStr = reverseStr.slice(spaceIndex+1);
        spaceIndex = reverseStr.indexOf(" ");
    }
    tempStr += reverseStr.split("").reverse().join("");
    return tempStr;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值