剑指Offer打卡

103 阅读1分钟

数组中重复的数字

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

//申请数组
var findRepeatNumber = function(nums) {
    let arr = new Array(nums.length);
    for(let i =0;i<nums.length;i++){
        if(arr[nums[i]]) {
            return nums[i];
        }else{
            arr[nums[i]]=1
        }   
    }
    return -1;
};

//不申请额外空间
var findRepeatNumber = function(nums) {
   let i=0;
   while(i<nums.length){
       if(nums[i]!=i&&nums[nums[i]]!=nums[i]){
            //交换
        nums[i]^=nums[nums[i]];
        nums[nums[i]]^=nums[i];
        nums[i]^=nums[nums[i]];

       }else if(nums[i]==i){
           i++;
       }
       else return nums[i];
   }
   return -1;
};

二维数组查找变量

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

//二分查找
var findNumberIn2DArray = function(matrix, target) {
    for(let i =0;i<matrix.length;i++){
    //遍历每一行的元素 如果matrix[i][0] <=target<= matrix[i][matrix[0].length-1]
    
        if(matrix[i][0]<=target&&matrix[i][matrix[0].length-1]>=target){
            let l = 0,r = matrix[0].length-1
            //二分查找
            while(l<=r){
                let mid =parseInt((r-l)/2)+l;
                if(matrix[i][mid]>target){
                    r = mid-1;

                }else if(matrix[i][mid]<target){
                    l = mid+1;
                }else {
                    return true;
                }
            }


        }
    }
    return false;
};



翻转链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回) 遍历每个节点 ,node.val放入数组中

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。***

假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

 preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]

3根

9左子树

15 20 7 右子树

20根


var buildTree = function(preorder, inorder) {
    if(!preorder.length)return null;//根左右
    let map = {};

         let s1 = new TreeNode();
          s1.val = preorder[0];
          if(preorder.length==1)return s1;
           //找到inorder的头
    let index =inorder.indexOf(preorder[0])//中序遍历中找到根节点 前面的是左子树 右边的是右子树
    let leftArr = inorder.slice(0,index),rightArr = inorder.slice(index+1);
    if(leftArr.length)s1.left = buildTree(preorder.slice(1,1+leftArr.length),leftArr)
    if(rightArr.length)s1.right = buildTree(preorder.slice(1+leftArr.length,leftArr.length+rightArr.length+1),rightArr)

   
    return s1;


};

旋转数组的最小数字 采用二分法

中间元素和右指针比较,更新左右指针 中间元素>右指针元素 更新 左指针 中间元素 < 右指针元素 更新右指针