剑指offer - 知识迁移能力

1.数字在排序数组中出现的次数

问题描述:

统计一个数字在排序数组中出现的次数。

function GetNumberOfK(data, k) {
  // write code here
  var count = 0;
  data.forEach((ele) => {
    if (ele == k) {
      count++;
    }
  });
  return count;
}

2.二叉树的深度

问题描述:

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */

function TreeDepth(pRoot) {
  // write code here
  if (pRoot === null) {
    return 0;
  }
  var left = TreeDepth(pRoot.left);
  var right = TreeDepth(pRoot.right);
  return Math.max(left, right) + 1;
}

3.平衡二叉树

问题描述:

输入一棵二叉树,判断该二叉树是否是平衡二叉树。

平衡二叉树:它是一棵空树或它的左右两个子树的高度差的绝对值不超过 1,并且左右两个子树都是一棵平衡二叉树。

function IsBalanced_Solution(pRoot) {
  return depth(pRoot) !== -1;
}

// 用递归来判断root是不是平衡二叉树,如果不是则返回最大的深度,如果不是则返回-1
function depth(root) {
  if (root === null) return 0;
  var left = depth(root.left);
  if (left === -1) return -1;
  var right = depth(root.right);
  if (right === -1) return -1;
  if (Math.abs(left - right) > 1) {
    return -1;
  } else {
    return 1 + Math.max(left, right);
  }
}

4.数组中只出现一次的数字

问题描述:

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

function FindNumsAppearOnce(array) {
  // write code here
  // return list, 比如[a,b],其中ab是出现一次的两个数字
  var list = [];
  array.forEach((item) => {
    if (array.indexOf(item) === array.lastIndexOf(item)) {
      list.push(item);
    }
  });
  return list;
}

5.和为 S 的连续正数序列

问题描述:

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

输出描述:

输出所有和为 S 的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序

解题思路:

因为要求连续的数列和,所以这是一个等差数列,并且我们想到用双指针来做,slow,fast。

等差数列:current(当前值)=(fast-slow+1)(fast+slow)/2

初始化 slow=1 和 fast=2.(因为考虑要覆盖到所有情况,所以赋值为两个较小的数)

只要满足 slow<fast,循环就可进行。

将 current 和 sum 进行比较

  • 若 current==sum,即 slow 和 fast 之间的数满足序列要求,所以遍历 slow 和 fast 之间的所有数,存入一个数组。之后 slow++(因为要求的所有的连续正数序列,所以要不断的右移,这步不能少)。
  • current<slow,则表明当前值小于 sum,需要 fast++,
  • current>slow,则表明当前值大于 sum,需要减小当前值,即 slow++;
function FindContinuousSequence(sum) {
  // write code here
  var res = [];
  var slow = 1;
  var fast = 2; //快慢指针
  while (slow < fast) {
    var current = ((fast - slow + 1) * (fast + slow)) / 2;
    if (current === sum) {
      var temp = [];
      for (let i = slow; i <= fast; i++) {
        temp.push(i);
      }
      res.push(temp);
      slow++;
    } else if (current < sum) {
      fast++;
    } else {
      slow++;
    }
  }
  return res;
}

6.和为 S 的两个数字

问题描述:

输入一个递增排序的数组和一个数字 S,在数组中查找两个数,使得他们的和正好是 S,如果有多对数字的和等于 S,输出两个数的乘积最小的。

输出描述:

对应每个测试案例,输出两个数,小的先输出。

方法一:

解题思路:

千万不要被题目误导了,因为数组是递增的,所有两个数乘积最小一定是两端的数,不会是中间的数,那只要用两个指针 low 和 high,初始,low 指向首部,high 指向尾部,判断:

  • 当这两个指针对应的数相加和不为 sum 而且 low 比 high 小的时后,继续判断:

    • 如果和大于 sum,说明 high 指针对应的数太大了,high--,往前找
    • 如果和小于 sum,说明 low 指针对应的数太小了,low++,往后找
  • 当这两个指针对应的数相加和为 sum 时,直接返回这两个数

  • 否则返回空数组,表示不存在

function FindNumbersWithSum(array, sum) {
  // write code here
  var low = 0; //此指针指向第一个数
  var high = array.length - 1; //此指针指向第二个数
  while (array[low] + array[high] !== sum && low < high) {
    if (array[low] + array[high] > sum) {
      high--;
    } else {
      low++;
    }
  }
  if (array[low] + array[high] === sum) {
    return [array[low], array[high]];
  }
  return [];
}

方法二:

function FindNumbersWithSum(array, sum) {
  // write code here
  var res = [];
  for (let i = 0; i < array.length; i++) {
    var num = sum - array[i];
    if (array.indexOf(num) !== -1) {
      res.push(array[i], num);
      break;
    }
  }
  return res;
}

7.左旋转字符串

问题描述:

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

解题思路:

主要是注意当 str 不存在返回空字符串即可

function LeftRotateString(str, n) {
  // write code here
  if (!str) return "";
  var n = n % str.length;
  return str.slice(n) + str.slice(0, n);
}

8.翻转单词顺序列

问题描述:

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

function ReverseSentence(str) {
  // write code here
  return str.split(" ").reverse().join(" ");
}
posted @ 2020-04-17 23:12  木子呆头  阅读(125)  评论(0编辑  收藏  举报