华为OD前端算法面试

2,843 阅读1分钟

题目

给你一串未加密的字符串s,需要对字符串进行加密,通过对字符串每一个字母进行改变实现加密,改变方式是对字母进行一定量的偏移,这里我们偏移的意思是把这个字母变成排在自己后面的那个字母,例如a变成b,b变成c,c变成d,y变成z,特别地,z变成a。加密方式是在每一个字母s[i]偏移斐波拉契数列a[i]的量,斐波拉契数列是a[1] = 1, a[2] = 1, a[i] = a[i-1] + a[i-2],例如:原文uvwxyz加密后vwyadg,其中偏移量分别为1,1,2,3,5,8。
解答要求:时间限制2000ms,内存限制:64mb
输入
第一行为一个整数T(1<=T<=1000), 表示有T组测试数据。每组数据包含一行,有原文s(只含有大小写字母与,长度小于50)。
输出
每组测试数据输出一行,表示字符串的密文
样式
输入样例
uvwxyz
ABcde
输出样式
vwyadh
BCegj

解题时间大概是40min

解题思路

  1. 求出斐波拉契数组
  2. 字符转变成字符串数组,遍历字符串数组
  3. 在每次遍历中,找出字符的在a-z中的位置,以及对应的偏移值
  4. 根据位置和偏移值求出新字符
  5. 根据原字符的大小写形式,来确定新字符是不是大小写
let letters = 'abcdefghijklmnopqrstuvwxyz'
const str1 = 'uvwxyz'
const str2 = 'ABcde'

// 生成斐波拉契数组
const febList = new Array(49).fill().reduce((result, item, i) => {
  if(i < 2) {
    result.push(1)
  } else {
    result[i] = result[i-1] + result[i-2]
  }
  return result
}, [])

// 生成
function decode(str) {
  let arr = [...str]
  return arr.reduce((result, item, index) => {
    // 字符偏移量
    let offset = febList[index]
    let index2 = offset + letters.indexOf(item.toLowerCase())
    // 字符位置
    let index3 = index2 >= letters.length ? (index2 + 1) % letters.length - 1 : index2
    // 偏移后的字符
    let letter = letters.charAt(index3)
    // 判断原字符的大小写
    if(item === item.toLowerCase()) {
      return result += letter
    } else {
      return result += letter.toUpperCase()
    }
  }, '')
}

const start = Date.now()

for(let i = 0; i < 500; i++) {
  console.log(decode(str1))
  console.log(decode(str2))  
}

const end = Date.now()
console.log(end - start) // 129ms左右

总结

  1. 需要读懂题目,在写代码前先理顺思路,由于紧张,我在题目和需求没读懂就开始写代码了,浪费了好多时间
  2. 由于是视频在线编程面试,感觉很不适应,内心比较紧张,导致思路很乱,脑子有时会空白,可以先在编辑器上把解题思路列出来,然后一步一步地去实现
  3. 需要更多地去进行这种面试,让自己不再紧张