每日一道题

Posted by Youzi Blog on April 22, 2019

每日一道面试题

前言

由git仓库:https://github.com/Advanced-Frontend/Daily-Interview-Question提供的面试问题,做一个自己的每日答题记录。

先将已有的放上来,有的问题是选择性记录的。

55题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* 第 55 题:某公司 1 到 12 月份的销售额存在一个对象里面,
如下:{ 1: 222, 2: 123, 5: 888 } ,
请把数据处理为如下结构:[222, 123, null, null, 888, null, null, null, null, null, null, null]。
*/

// 自己写的 low B function

function objToArr (obj) {
  let ary = new Array(12).fill(null)
  ary.forEach((el, index, ary) => {
    ary[index] = obj[index + 1] ? obj[index + 1] : null
    // console.log(el);
  })
  return ary
}
console.log(objToArr({ 1: 222, 2: 123, 5: 888 }))

// 大佬们写的 NB function

function objToArrNB (obj) {
  return Array.from({ ...obj, length: 13 }).slice(1)
  // retrun Array.from({length: 12}, (el, index) => (obj[index + 1] || null))
}
console.log(objToArrNB({ 1: 222, 2: 123, 5: 888 }))

56题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 选择排序

function selectSort (ary) {
  for (let i = 0; i < ary.length; i++) {
    let min = ary[i]
    let pos = i
    for (let j = i + 1; j < ary.length; j++) {
      if (min > ary[j]) {
        pos = j
        min = ary[j]
      }
    }
    [ary[i], ary[pos]] = [ary[pos], ary[i]]
  }
  return ary
}
console.log(selectSort([1, 2, 3, 1, 2, 3, 4, 5, 6, 2, 3, 4, 1, 1, 2, 9]))

// 冒泡排序

function bubbleSort (ary) {
  for (let i = ary.length; i > 1; i--) {
    for (let j = 0; j < i; j++) {
      if (ary[j] > ary[j + 1]) {
        [ary[j], ary[j + 1]] = [ary[j + 1], ary[j]]
      }
    }
  }
  return ary
}
console.log(bubbleSort([1, 2, 3, 1, 2, 3, 4, 5, 6, 2, 3, 4, 1, 1, 2, 9]))

59题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/* 第 59 题:给定两个数组,写一个方法来计算它们的交集。

例如:给定 nums1 = [1, 2, 2, 1],nums2 = [2, 2],返回 [2, 2]。 */

// 思路:遍历数组1,对每个元素判断其是否在数组2中,存在则提出来放到一个新数组里,并且从数组2中剔除,以确保下一次遍历不会出现重复的。
// 由于Array.splice()函数效率比较低,所以采用空间换取时间的方式,剔除的过程是将其他非交集元素放到新数组里。
// 想了想,还是用简单的splice吧。

function intersect (ary1, ary2) {
  let longAry, shortAry
  // 不取长短数组也行吧。
  if (ary1.length > ary2.length) {
    longAry = ary1
    shortAry = ary2
  } else {
    longAry = ary2
    shortAry = ary1
  }
  let tmpAry = []
  try {
    longAry.forEach(el => {
      if (shortAry.length === 0) {
        throw new Error('short array.lenth === 0')
      }
      let index = shortAry.indexOf(el)
      if (index > -1) {
        // 短数组中存在元素的情况
        shortAry.splice(index, 1)
        tmpAry.push(el)
      }
    })
  } catch (error) {
    console.log(error)
  }
  return tmpAry
}
console.log(intersect([1, 2, 2, 1], [2, 2]))

// 一种hash表的写法,时间复杂度也降下来了
// 先遍历数组1,存个hash表,保存值和出现的次数
// 再遍历数组2,如果hash表里有这个元素,就放到result数组里,并把出现次数-1;

const intersect = (nums1, nums2) => {
  const map = {}
  const res = []
  for (let n of nums1) {
    if (map[n]) {
      map[n]++
    } else {
      map[n] = 1
    }
  }
  for (let n of nums2) {
    if (map[n] > 0) {
      res.push(n)
      map[n]--
    }
  }
  return res
}

67题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 第 67 题:随机生成一个长度为 10 的整数类型的数组,例如 [2, 10, 3, 4, 5, 11, 10, 11, 20],将其排列成一个新数组,要求新数组形式如下,例如 [[2, 3, 4, 5], [10, 11], [20]]。
// 我的理解是把连续的元素组成一个数组,例如1,2,3,4组成一个,9,10,11,12组成一个
// 随机生成数组
const randomAry = (n = 10, range = { min: 1, max: 20 }) => {
  let ary = new Array(n).fill(0)
  ary = ary.map((val) => {
    val = Math.floor(Math.random() * (range.max - range.min + 1) + range.min)
    return val
  })
  console.log('random: ', ary)
  return ary
}
let ary = randomAry()
// 去重
ary = Array.from(new Set(ary))
// 排序
ary.sort((a, b) => a - b)
console.log('sorted: ', ary)
// 保存结果
let newAry = []
for (let i = 0; i < ary.length; i++) {
  let tmpAry = [ary[i]]
  // index用于跳过已经处理过的数组元素,为什么让初始值等于数组长度呢?因为内层循环执行最后一步时,index = j - 1这一条语句会被跳过,为了不出现死循环,所以让初始值等于数组长度
  let index = ary.length
  for (let j = i + 1, count = 1; j < ary.length; j++, count++) {
    if (ary[i] + count === ary[j]) {
      tmpAry.push(ary[j])
    } else {
      index = j - 1
      break
    }
  }
  i = index
  // debugger
  newAry.push(tmpAry)
}
console.log('result', newAry)

69题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 第 69 题: 如何把一个字符串的大小写取反(大写变小写小写变大写),例如 ’AbC' 变成 'aBc' 。

const reverseStr = (str) => {
  let tmpAry = str.split('')
  let resultAry = []
  let a = 'a'.charCodeAt()
  let A = 'A'.charCodeAt()
  tmpAry.map((val) => {
    // debugger
    if (val <= 'Z' && val >= 'A') {
      resultAry.push(String.fromCharCode(val.charCodeAt() + (a - A)))
    } else if (val <= 'z' && val >= 'a') {
      resultAry.push(String.fromCharCode(val.charCodeAt() - (a - A)))
    } else {
      resultAry.push(val)
    }
  })
  return resultAry.join('')
}
console.log(reverseStr('aBCDefgh!@##%^$^*!@#$%'))

看到个大佬牛批的写法,用正则替换,贴一下。

1
2
3
'AbcDefGh'.replace(/[a-zA-Z]/g, function (a) {
  return /[a-z]/.test(a) ? a.toUpperCase() : a.toLowerCase()
})

71题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// 第 71 题: 实现一个字符串匹配算法,从长度为 n 的字符串 S 中,查找是否存在字符串 T,T 的长度是 m,若存在返回所在位置。
// 以下解法均只匹配第一次出现的子串,不考虑多次重复出现的情况。
// 暴力算法,不用api

const strMatch = (S, T) => {
  let sLen = S.length, tLen = T.length
  if (!sLen || !tLen || sLen < tLen) {
    return -1
  }
  for (let i = 0; i < sLen - tLen + 1; i++) {
    let tmp = i
    let matched = true
    for (let j = 0; j < tLen; j++) {
      if (S[tmp] !== T[j]) {
        matched = false
        break
      } else {
        tmp++
      }
    }
    if (matched) {
      return i
    }
  }
  return -1
}
console.log(strMatch('aaaaaaaaaaabcdfdfdfdfdfdf', 'aaaaaaaaaaa'))

// 经典的KMP解法,难,不写了。

// 调用JS各种库函数的解法

const matchIndexOf = (S, T) => {
  return S.indexOf(T)
}
console.log(matchIndexOf('aaaaaaaaaaabcdfdfdfdfdfdf', 'aaaaaaaaaaa'));

const matchSearch = (S, T) => {
  return S.search(T)
}

const matchSplit = (S, T) => {
  let sLen = S.length, tLen = T.length
  if (!sLen || !tLen || sLen < tLen) {
    return -1
  }
  let ary = S.split(T)
  if (ary.length > 1) {
    return ary[0].length
  }
}