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

400 阅读3分钟

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

31. 旋转图像 (rotate-image)

标签

  • 二维数组
  • 坐标变换,几何
  • 中等

题目

leetcode 传送门

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

给出一个二维数组,要求顺时针旋转 90 度。

相关知识

顺时针旋转的几何拆分,其实就是按照对角线对折,再按中轴对折就是结果。看下面图例

(1), 2, 3   对角线折叠   (1), 4, 7   按中线对折     7 |4| 1
4, (5), 6     ->        2, (5), 8    变->        8 |5| 2
7, 8, (9)  哪条对角都行   3, 6, (9)    化          9 |6| 3

基本思路

那这个思路就太简单了

  1. 获取行列数
  2. 按对角线折叠(随便哪个)
  3. 按中线折叠(跟上面对角线对应就成)

写法实现

var rotate = function(matrix) {
  // 获取行/列数
  let row = matrix.length
  if (row <= 0) {
    return
  }
  let column = matrix[0].length
  // 先进行对角线变换
  for (i = 0; i < row; i++) {
    for (j = i + 1; j < column; j++) {
      let temp = matrix[i][j]
      matrix[i][j] = matrix[j][i]
      matrix[j][i] = temp
    }
  }
  // 找到对称轴,再轴对称翻转下
  let halfColumn = Math.ceil(column / 2)
  for (i = 0; i < row; i++) {
    for (j = 0; j < halfColumn; j++) {
      temp = matrix[i][j]
      matrix[i][j] = matrix[i][column-j-1]
      matrix[i][column-j-1] = temp
    } 
  }
};

let matrix =
[
  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
]
console.log(rotate(matrix))

32. 字母异位词分组 (group-anagrams)

标签

  • Map
  • 中等

题目

leetcode 传送门

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

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

输入: ["eat", "tea", "tan", "ate", "nat", "bat"]
输出:
[  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]

相关知识

MDN: Array.from() 方法从一个类似数组可迭代对象创建一个新的,浅拷贝的数组实例。

Array.from() 可以通过以下方式来创建数组对象:

  • 伪数组对象(拥有一个 length 属性和若干索引属性的任意对象)
  • 可迭代对象(可以获取对象中的元素,如 Map和 Set 等)

下面是一些用法示例:

  • String 生成数组
Array.from('foo');
// [ "f", "o", "o" ]
  • Set 生成数组
const set = new Set(['foo', 'bar', 'baz', 'foo']);
Array.from(set);
// [ "foo", "bar", "baz" ]
  • Map 生成数组
const map = new Map([[1, 2], [2, 4], [4, 8]]);
Array.from(map);
// [[1, 2], [2, 4], [4, 8]]

const mapper = new Map([['1', 'a'], ['2', 'b']]);
Array.from(mapper.values());
// ['a', 'b'];

Array.from(mapper.keys());
// ['1', '2'];
  • 类数组对象(arguments)生成数组
function f() {
  return Array.from(arguments);
}

f(1, 2, 3);
// [ 1, 2, 3 ]
  • 在 Array.from 中使用箭头函数
Array.from([1, 2, 3], x => x + x);
// [2, 4, 6]

Array.from({length: 5}, (v, i) => i);
// [0, 1, 2, 3, 4]
  • 序列生成器(指定范围)
// Sequence generator function (commonly referred to as "range", e.g. Clojure, PHP etc)
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));

// Generate numbers range 0..4
range(0, 4, 1);
// [0, 1, 2, 3, 4]

// Generate numbers range 1..10 with step of 2
range(1, 10, 2);
// [1, 3, 5, 7, 9]

// Generate the alphabet using Array.from making use of it being ordered as a sequence
range('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1).map(x => String.fromCharCode(x));
// ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
  • 数组去重合并
function combine(){
    let arr = [].concat.apply([], arguments);  //没有去重复的新数组
    return Array.from(new Set(arr));
}

var m = [1, 2, 2], n = [2,3,3];
console.log(combine(m,n));                     // [1, 2, 3]

写法实现

var groupAnagrams = function(strs) {
  let map = new Map()
  strs.map(item => {
    // 取排序后子串做"键",同组子串排序后是相同的
    let key = Array.from(item).sort().join('')
    let childList = map.has(key) ? map.get(key) : []
    childList.push(item)
    map.set(key, childList)
  })
  // 由于获得的是个Map,转换下变成数组就行
  return Array.from(map.values());
};

console.log(groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]))

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

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

参考