zoukankan      html  css  js  c++  java
  • 剑指offer

    1.数组中出现次数超过一半的数字

    问题描述:

    数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为 9 的数组[1,2,3,2,2,2,5,4,2]。由于数字 2 在数组中出现了 5 次,超过数组长度的一半,因此输出 2。如果不存在则输出 0。

    function MoreThanHalfNum_Solution(numbers) {
      // write code here
      var len = numbers.length;
      var obj = {};
      numbers.forEach((item) => {
        if (!obj[item]) {
          obj[item] = 1;
        } else {
          obj[item]++;
        }
      });
      for (let key in obj) {
        if (obj[key] > len / 2) {
          return key;
        }
      }
      return 0;
    }
    

    2.最小的 K 个数

    问题描述:

    输入 n 个整数,找出其中最小的 K 个数。例如输入 4,5,1,6,2,7,3,8 这 8 个数字,则最小的 4 个数字是 1,2,3,4,。

    方法一:快排

    function GetLeastNumbers_Solution(input, k) {
      // write code here
      if (k > input.length) return [];
      quickSort(input);
      return input.slice(0, k);
    }
    
    function quickSort(input, left = 0, right = input.length - 1) {
      if (left >= right) return;
      var baseId = left;
      var baseVal = input[baseId];
      var i = left;
      var j = right;
      while (i < j) {
        while (j > i && input[j] >= baseVal) {
          j--;
        }
        while (i < j && input[i] <= baseVal) {
          i++;
        }
        [input[i], input[j]] = [input[j], input[i]];
      }
      [input[baseId], input[j]] = [input[j], input[baseId]];
      quickSort(input, left, j - 1);
      quickSort(input, j + 1, right);
      return input;
    }
    

    方法二:冒泡排序

    function GetLeastNumbers_Solution(input, k) {
      // write code here
      if (k > input.length) return [];
      for (let j = input.length - 1; j >= input.length - k; j--) {
        for (let i = 0; i < j; i++) {
          if (input[i] < input[i + 1]) {
            [input[i], input[i + 1]] = [input[i + 1], input[i]];
          }
        }
      }
      var res = [];
      while (k > 0) {
        res.push(input.pop());
        k--;
      }
      return res;
    }
    

    方法三:sort 排序

    function GetLeastNumbers_Solution(input, k) {
      // write code here
      if (input.length < k) {
        return [];
      }
      input.sort((a, b) => a - b);
      return input.slice(0, k);
    }
    

    3.连续子数组的最大和

    问题描述:

    HZ 偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为 8(从第 0 个开始,到第 3 个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是 1)

    /*
    举例:array = [1, -2, 3, 10, -4, 7, 2, -5]
    初始化 max = 1, temp = 1
    i = 1时, temp = -1, max = 1
    i = 2时, temp = 3,  max = 3
    i = 3时, temp = 13, max = 13
    i = 4时, temp = 9 , max = 13
    i = 5时, temp = 16, max = 16
    i = 6时, temp = 18, max = 18
    i = 7时, temp = 13, max = 18;
    */
    
    function FindGreatestSumOfSubArray(array) {
      // write code here
      var max = array[0],
        sum = array[0];
      for (let i = 1; i < array.length; i++) {
        if (sum <= 0) {
          sum = array[i]; //sum是负数说明前面的数没有贡献,重新赋值一个数
        } else {
          sum += array[i]; //sum不是负数说明当前值有贡献
        }
        if (sum > max) {
          max = sum;
        }
      }
      return max;
    }
    

    4.整数中 1 出现的次数(从 1 到 n 整数中 1 出现的次数)

    题目描述:

    求出 1~13 的整数中 1 出现的次数,并算出 100~1300 的整数中 1 出现的次数?为此他特别数了一下 1~13 中包含 1 的数字有 1、10、11、12、13 因此共出现 6 次,但是对于后面问题他就没辙了。ACMer 希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中 1 出现的次数(从 1 到 n 中 1 出现的次数)。

    方法一:对于每个数来说求个位只需对 10 取余(%10),然后将原数除以 10 取整,再对 10 取余拿到十位...依次类推

    function NumberOf1Between1AndN_Solution(n) {
      // write code here
      var count = 0;
      for (let i = n; i > 0; i--) {
        for (let j = i; j > 0; j = parseInt(j / 10)) {
          //对j/10取整
          if (j % 10 === 1) {
            count++;
          }
        }
      }
      return count;
    }
    

    方法二:笨方法,将 1 到 n 转换成字符串拼接起来,计算 1 的个数

    function NumberOf1Between1AndN_Solution(n) {
      // write code here
      var str = "";
      for (let i = 0; i <= n; i++) {
        str += i;
      }
      var res = str.split("").filter((ele) => ele === "1");
      return res.length;
    }
    

    5.把整数排成最小的数

    问题描述:

    输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为 321323。

    解题思路:

    将数组中的数字连接起来,排成一个最小的数字。将'大数'往后放'小数'往前放,如何定义'大数'和'小数'?比如说有两个数 a 和 b,如果 ab>ba 则 a 是'大数'b 是'小数',要排成 ba。

    于是,这道题目变成了一个排序问题,将能把组合出来的数字变大的数字往后排。我们这里需要自己定义一个比大小的比较方法。用冒泡排序,可以解决此题。

    function PrintMinNumber(numbers) {
      // write code here
      numbers.sort((a, b) => {
        return "" + a + b > "" + b + a ? 1 : -1; // ab 和 ba ASCII码值大的排在后面
        // return [a,b].join("")-[b,a].join("");
      });
      return numbers.join("");
    }
    
  • 相关阅读:
    hdu2438 三分
    hdu3786 找出直系亲属 水题
    hdu3786 找出直系亲属 水题
    hdu4561 连续最大积
    hdu4561 连续最大积
    hdu4604 不错的子序列问题
    hdu4604 不错的子序列问题
    hdu4450 不错的贪心
    hdu1722 切蛋糕
    hdu3768 spfa+全排列
  • 原文地址:https://www.cnblogs.com/muzidaitou/p/12722094.html
Copyright © 2011-2022 走看看