前端算法面试必刷题系列[28]

302 阅读4分钟

这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。

48. 简化路径 (simplify-path)

标签

  • 文字理解
  • 中等

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

给出一个 Unix 的文件路径,要求简化这个路径。

请注意,返回的 规范路径 必须遵循下述格式:

  • 始终以斜杠 '/' 开头。
  • 两个目录名之间必须只有一个斜杠 '/'
  • 最后一个目录名(如果存在)不能 以 '/'结尾。
  • 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 '.' 或 '..')。 返回简化后得到的规范路径

基本思路

思考一个问题 ..是回退上一级,一般目录层级只有两个数据结构,一个是树,一个是栈。新建一个栈stack为当前的路径。并将path以'/'分割成数组,两个/连续的中间是空字符串。遍历,并根据题意处理这些边界条件即可。

这题主要是文字理解和注意细节

基本步骤

  1. 先把 path 用 / 进行分割成数组。结果含有以下几种情况
    • ''
    • 'pathName'
    • '/'
    • '.'
    • '..'
  2. 分情况处理
    • 遇到 . 或者为''时,不修改当前 stack。
    • 遇到pathName时,推入 stack 中
    • 遇到 .. 时,stack 栈顶元素出栈,回退到上一个路径
  3. 这样,遍历结束,返回 '/' + stack.join('/') 就会变成一个标准路径

写法实现

// 上面解释非常清晰,自解释代码
var simplifyPath = function(path) {
  const stack = [];
  const pathArr = path.split('/');
  pathArr.map(item => {
    if (item === '' || item === '.') {
      // do nothing
    } else if (item === '..') {
      stack.pop();
    } else {
      stack.push(item);
    }
  })
  return '/' + stack.join('/')
};
console.log(simplifyPath('/home/'))

49. 矩阵置零 (set-matrix-zeroes)

标签

  • Set
  • 中等

题目

leetcode 传送门

这里不贴题了,leetcode打开就行,题目大意:

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列所有元素都设为 0 。请使用 原地 算法。

屏幕快照 2021-03-27 下午4.06.52.png

输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[1,0,1],[0,0,0],[1,0,1]]

相关知识

Set

Set 对象允许你存储任何类型唯一值,无论是原始值或者是对象引用

Set对象是值的集合,你以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即 Set 中的元素是唯一的。跟数学中的集合类似,不过数学集合强调一个无序性,但计算机总需要有个迭代顺序。

另外,NaN和undefined都可以被存储在Set 中, NaN之间被视为相同的值(NaN被认为是相同的,尽管 NaN !== NaN)。

经典用法,数组去重

const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]
console.log([...new Set(numbers)])
// [2, 3, 4, 5, 6, 7, 32]

下面常用的 Api列下

  • Set.prototype.add() add() 方法用来向一个 Set 对象的末尾添加一个指定的值。
var mySet = new Set();

mySet.add(1);
mySet.add(5).add("some text"); // 可以链式调用

console.log(mySet);
// Set [1, 5, "some text"]

mySet.add(5).add(1);
console.log(mySet);
// Set [1, 5, "some text"]  // 重复的值没有被添加进去
  • Set.prototype.clear()

clear() 方法用来清空一个 Set 对象中的所有元素

  • Set.prototype.has()

has() 方法返回一个布尔值来指示对应的值value是否存在Set对象中

var mySet = new Set();
mySet.add('foo');

mySet.has('foo');  // 返回 true
mySet.has('bar');  // 返回 false

var set1 = new Set();
var obj1 = {'key1': 1};
set1.add(obj1);

set1.has(obj1);        // 返回 true
set1.has({'key1': 1}); // 会返回 false,因为其是另一个对象的引用
set1.add({'key1': 1}); // 现在 set1 中有2条(不同引用的)对象了

基本思路

这个题目就希望你使用原地,不增加额外空间是重点,所有操作在原数组上进行。 用两个 Set 来存哪行哪列是 0,然后再原地遍历置 0。

基本步骤

  1. 遍历 matrix 用两个 Set 记住有 0 的行列,为什么要用 Set结构,因为 Set中数据的唯一性
  2. 再遍历 matrix 原地置 0 即可,主要用 Set 数据结构的方法。非 js 的话写个去重也行。

写法实现

var setZeroes = function(matrix) {
    let [row, col] = [matrix.length, matrix[0].length]
  // 用两个 Set 记住有 0 的行列
  let [rowSet, colSet] = [new Set(), new Set()]
  for(let i = 0; i < row; i++){
    for(let j = 0; j < col; j++){
      if (matrix[i][j] === 0){
        rowSet.add(j)
        colSet.add(i)
      }
    }
  }
  // 只要 set 中含该行/列,当前元素置 0 
  for(let i = 0; i < row; i++){
    for(let j = 0; j < col; j++){
      if (rowSet.has(j) || colSet.has(i)) {
        matrix[i][j] = 0
      }
    }
  }
  return matrix
};

let matrix = [[1,1,1],[1,0,1],[1,1,1]]
console.log(setZeroes(matrix))

另外向大家着重推荐下这位大哥的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列

今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 搜索我的微信号infinity_9368,可以聊天说地 加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我 presious tower shock the rever monster,我看到就通过,暗号对不上不加哈,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧

参考