leetcodeの每周七道面试题_2020/11/1~2020/11/7

leetcode每周七题-初衷

  • 之前的每日一题系列,由于时间问题,直接贴的安大的微信群每日一题,大佬已经坚持到140多天了。
  • 为了向大佬学习,推出每日七道面试题。对于力扣大家应该挺熟悉的,毕竟想进BAT一线大厂,leetcode题必刷,接下来我带着大家一起学习吧(全程使用 javascript解题,不是最优解,只是提供一个思路)。

为什么要刷leetcode?游戏它不香?

  • 虽然刷题一直饱受诟病,不过不可否认刷题确实能锻炼我们的编程能力。
  • 虽然leetcode题目深度普遍偏低(知乎大佬说的),如果是为了面试,刷Leetcode还是很重要的。一是提高对简单题的熟悉程度,有一些听起来很轻松的题目,写过一次和没写过的临场表现可能会有很大的差距;二是可以见识一些大家都知道的奇技淫巧,有一些大公司就是喜欢考这种看似很巧妙,牵扯到知识的广度还是挺宽的。

2020/11/1(140. 单词拆分 II)

题目

  • 给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。
  • 说明:
    • 分隔时可以重复使用字典中的单词。
    • 你可以假设字典中没有重复的单词。

示例

  • 示例 1:
输入:
s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
输出:
[
  "cats and dog",
  "cat sand dog"
]
  • 示例2
输入:
s = "pineapplepenapple"
wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]
输出:
[
  "pine apple pen apple",
  "pineapple pen apple",
  "pine applepen apple"
]
解释: 注意你可以重复使用字典中的单词。
  • 示例3
输入:
s = "catsandog"
wordDict = ["cats", "dog", "sand", "and", "cat"]
输出:
[]

代码模版

/**
 * @param {string} s
 * @param {string[]} wordDict
 * @return {string[]}
 */
var wordBreak = function(s, wordDict) {

};

题解

/**
 * @param {string} s
 * @param {string[]} wordDict
 * @return {string[]}
 */
var wordBreak = function (s, wordDict) {
    const sIndex = s.length;
    const newWordDict = new Set(wordDict);//set 数据结构有has方法
    let hash = new Map();//存储循环过的从start截取i对应的数据
    function drt(start) {
        if (hash.has(start)) {//hash里有start,直接取对应的数据
            return hash.get(start);
        }
        if (start > sIndex - 1) {//start 最大值就是字符串最后一个索引 sIndex - 1
            return [[]];
        }
        let res = [];
        for (var i = start + 1; i <= sIndex; i++) {
            let str = s.slice(start, i);
            if (newWordDict.has(str)) {
                const items = drt(i);//循环把剩余字符串在newWordDict进行匹配,返回数组res [[string],]
                for (let item of items) {
                    res.push([str].concat(item));
                }
            }
            hash.set(start, res);//存储从start开始截取,对应的res数据
        }
        return res;
    }
    return drt(0).map((item) => item.join(" "));// [[string,string],[string,string]]  变成 ["string string","string string"]
};

2020/11/2(349. 两个数组的交集)

题目

  • 给定两个数组,编写一个函数来计算它们的交集。

示例

  • 示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
  • 示例2
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]

代码模版

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersection = function (nums1, nums2) {

};

题解

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersection = function (nums1, nums2) {
    let ary1 = new Set(nums1);//利用set去重,有has方法
    let ary2 = new Set(nums2);//set数据结构类数组,需要转成数组可以调数组上的方法
    return Array.from(ary2).filter((item) => ary1.has(item));//Array.from(ary2) 类数组转数组   
};

2020/11/3(941. 有效的山脉数组)

题目

  • 给定一个整数数组 A,如果它是有效的山脉数组就返回 true,否则返回 false。

  • 让我们回顾一下,如果 A 满足下述条件,那么它是一个山脉数组:

    A.length >= 3
    在 0 < i < A.length - 1 条件下,存在 i 使得:
    A[0] < A[1] < … A[i-1] < A[i]
    A[i] > A[i+1] > … > A[A.length - 1]

示例

  • 示例 1:
输入:[2,1]
输出:false
  • 示例2
输入:[3,5,5]
输出:false
  • 示例3
输入:[0,3,2,1]
输出:true

代码模版

/**
 * @param {number[]} A
 * @return {boolean}
 */
var validMountainArray = function (A) {

};

题解

/**
 * @param {number[]} A
 * @return {boolean}
 */
var validMountainArray = function (A) {
    if (A.length < 3) return false;
    let max = Math.max(...A);//找到最高点
    let index = A.indexOf(max);//拿到最高点的索引
    let i = 0;
    let isBoolean = true;
    let goUp = false;
    let goDown = false;
    while (i < A.length - 1) {
        if (i < index && A[i] < A[i + 1]) {//最高点之前是上升趋势
            i++;
            goUp = true;
        } else if (i >= index && A[i] > A[i + 1]) {//最高点之后是下降趋势
            i++;
            goDown = true;
        } else {//不满足上面就失败,break中止循环
            isBoolean = false;
            break;
        }
    }
    return goUp && goDown && isBoolean;
};

2020/11/4(57. 插入区间)

题目

  • 给出一个无重叠的 ,按照区间起始端点排序的区间列表。
  • 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。

示例

  • 示例 1:
输入:intervals = [[1,3],[6,9]], newInterval = [2,5]
输出:[[1,5],[6,9]]
  • 示例2
输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
输出:[[1,2],[3,10],[12,16]]
解释:这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。

代码模版

/**
 * @param {number[][]} intervals
 * @param {number[]} newInterval
 * @return {number[][]}
 */
var insert = function (intervals, newInterval) {

};

题解

/**
 * @param {number[][]} intervals
 * @param {number[]} newInterval
 * @return {number[][]}
 */
var insert = function (intervals, newInterval) {
    let res = [];
    intervals.push(newInterval);//合并到一个数组
    intervals.sort((a, b) => a[0] - b[0]);//按照数组中每一项(也是数组)的第一个值,从小到大进行排序
    res.push(intervals[0]);//把第一个先放到res中,从第二个值开始循环(索引为1)
    for (var i = 1; i < intervals.length; i++) {
        if (res[res.length - 1][1] < intervals[i][0]) {//当res数组中最后一个的第二个值,小于 intervals[i]中的第一个值,说明没有区间不重叠
            res.push(intervals[i]);
        } else if (res[res.length - 1][1] < intervals[i][1]) {//当res数组中最后一个的第二个值,大于或等于 intervals[i]中的第一个值,小于i intervals[i]中的第二个值,说明有区间重叠,直接把 intervals[i]中的第二个值给es数组中最后一个的第二个值
            res[res.length - 1][1] = intervals[i][1];
        }
    }
    return res;
};

2020/11/5(127. 单词接龙)

题目

  • 给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:
    • 每次转换只能改变一个字母。
    • 转换过程中的中间单词必须是字典中的单词。
  • 说明:
    • 如果不存在这样的转换序列,返回 0。
    • 所有单词具有相同的长度。
    • 所有单词只由小写字母组成。
    • 字典中不存在重复的单词。
    • 你可以假设 beginWord 和 endWord 是非空的,且二者不相同。

示例

  • 示例 1:
输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

输出: 5

解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
     返回它的长度 5。
  • 示例2
输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

输出: 0

解释: endWord "cog" 不在字典中,所以无法进行转换。

代码模版

/**
 * @param {string} beginWord
 * @param {string} endWord
 * @param {string[]} wordList
 * @return {number}
 */
var ladderLength = function (beginWord, endWord, wordList) {

};

题解

/**
 * @param {string} beginWord
 * @param {string} endWord
 * @param {string[]} wordList
 * @return {number}
 */
var ladderLength = function (beginWord, endWord, wordList) {
    if (beginWord === endWord) return 1
    let newSetWordList = new Set(wordList);
    let que = [];
    que.push([beginWord, 1])//第一次默认值,beginWord,默认长度1
    while (que.length) {
        for (var i = 0; i < que.length; i++) {
            let [newBeginWord, level] = que.shift()
            if (newBeginWord === endWord) {//相等时,返回长度
                return level
            }
            for (var w = 0; w < newBeginWord.length; w++) {//循环需要转换的字符串
                for (var j = 97; j <= 122; j++) {// 26个小写字母(ascii码   http://ascii.911cha.com/)
                    let newStr = newBeginWord.slice(0, w) + String.fromCharCode(j) + newBeginWord.slice(w + 1)//hit -》 xit hxt hix  x代表26个小写字母 
                    if (newSetWordList.has(newStr)) {
                        que.push([newStr, level + 1]) //把转换后的newStr放到数组中,长度+1
                        newSetWordList.delete(newStr)//匹配到删除
                    }
                }
            }
        }

    }
    return 0;
};

2020/11/6(1356. 根据数字二进制下 1 的数目排序)

题目

  • 给你一个整数数组 arr 。请你将数组中的元素按照其二进制表示中数字 1 的数目升序排序。

  • 如果存在多个数字二进制中 1 的数目相同,则必须将它们按照数值大小升序排列。

  • 请你返回排序后的数组。

示例

  • 示例 1:
输入:arr = [0,1,2,3,4,5,6,7,8]
输出:[0,1,2,4,8,3,5,6,7]
解释:[0] 是唯一一个有 0 个 1 的数。
[1,2,4,8] 都有 1 个 1 。
[3,5,6] 有 2 个 1 。
[7] 有 3 个 1 。
按照 1 的个数排序得到的结果数组为 [0,1,2,4,8,3,5,6,7]
  • 示例2
输入:arr = [1024,512,256,128,64,32,16,8,4,2,1]
输出:[1,2,4,8,16,32,64,128,256,512,1024]
解释:数组中所有整数二进制下都只有 1 个 1 ,所以你需要按照数值大小将它们排序。
  • 示例3
输入:arr = [10000,10000]
输出:[10000,10000]
  • 示例4
输入:arr = [2,3,5,7,11,13,17,19]
输出:[2,3,5,17,7,11,13,19]
  • 示例5
输入:arr = [10,100,1000,10000]
输出:[10,100,10000,1000]
  • 提示:

1 <= arr.length <= 500
0 <= arr[i] <= 10^4

代码模版

/**
 * @param {number[]} arr
 * @return {number[]}
 */
var sortByBits = function (arr) {

};

题解

/**
 * @param {number[]} arr
 * @return {number[]}
 */
var sortByBits = function (arr) {
  return arr.sort((a, b) => {
    let aIndex = a.toString(2).match(/1/g)?.length || 0;//a.toString(2) 把数组转换成二进制的字符串,.match(/1/g)?.length || 0  匹配到1的数量没有就是0
    let bIndex = b.toString(2).match(/1/g)?.length || 0;
    if (aIndex < bIndex || (aIndex <= bIndex && a < b)) {//aIndex < bIndex  按照1的数量从小到大,aIndex <= bIndex && a < b 如果1的数量相同  从小到大排序
      return -1;
    }
  });
};
  • 也可以 把match换成replace
/**
 * @param {number[]} arr
 * @return {number[]}
 */
var sortByBits = function (arr) {
    return arr.sort((a, b) => {
        let aIndex = a.toString(2).replace(/0/g, "").length;
        let bIndex = b.toString(2).replace(/0/g, "").length;
        if (aIndex < bIndex || (aIndex <= bIndex && a < b)) {
            return -1;
        }
    });
};
  • 还可以存到newArr 中
/**
 * @param {number[]} arr
 * @return {number[]}
 */
var sortByBits = function (arr) {
    let newArr = [];
    for (var i = 0, id = 0; i < arr.length; i++ , id = 0) {
        newArr.push({
            item: arr[i],
            number:
                arr[i].toString(2).replace(/0/g, '').length,
        });
    }
    return newArr
        .sort((a, b) => {
            if (a.number < b.number || (a.number === b.number && a.item < b.item)) {
                return -1;
            }
        })
        .map((item) => item.item);
};

2020/11/7(327. 区间和的个数)

题目

给定一个整数数组 nums,返回区间和在 [lower, upper] 之间的个数,包含 lower 和 upper。
区间和 S(i, j) 表示在 nums 中,位置从 i 到 j 的元素之和,包含 i 和 j (i ≤ j)。

说明:
最直观的算法复杂度是 O(n2) ,请在此基础上优化你的算法。

示例

  • 示例 1:
输入: nums = [-2,5,-1], lower = -2, upper = 2,
输出: 3 
解释: 3个区间分别是: [0,0], [2,2], [0,2],它们表示的和分别为: -2, -1, 2。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-of-range-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

代码模版

/**
 * @param {number[]} nums
 * @param {number} lower
 * @param {number} upper
 * @return {number}
 */
var countRangeSum = function (nums, lower, upper) {

};

题解

/**
 * @param {number[]} nums
 * @param {number} lower
 * @param {number} upper
 * @return {number}
 */
var countRangeSum = function (nums, lower, upper) {
    let n = 0;
    for (var i = 0; i < nums.length; i++) {//循环nums.length次
        let item=0;
        for (var j = i; j < nums.length; j++) {//从i项开始循环
            item += nums[j];
            if(item >=lower&&item<=upper){
                n++
            }

        }
    }
    return n
};

猜你喜欢

转载自blog.csdn.net/Sheng_zhenzhen/article/details/109544947