手写算法

https://leetcode-cn.com/problems/shortest-distance-to-a-character

  • 题目描述:给你一个字符串 s 和一个字符 c ,且 c 是 s 中出现过的字符。返回一个整数数组 answer ,其中 answer.length == s.length 且 answer[i] 是 s 中从下标 i 到离它 最近 的字符 c 的 距离 。两个下标 i 和 j 之间的 距离 为 abs(i - j) ,其中 abs 是绝对值函数。
  • 示例

    1. 输入:s = "loveleetcode", c = "e"
    2. 输出:[3,2,1,0,1,0,0,1,2,2,1,0]
    3. 解释:字符 'e' 出现在下标 356 11 处(下标从 0 开始计数)。
    4. 距下标 0 最近的 'e' 出现在下标 3 ,所以距离为 abs(0 - 3) = 3
    5. 距下标 1 最近的 'e' 出现在下标 3 ,所以距离为 abs(1 - 3) = 2
    6. 对于下标 4 ,出现在下标 3 和下标 5 处的 'e' 都离它最近,但距离是一样的 abs(4 - 3) == abs(4 - 5) = 1
    7. 距下标 8 最近的 'e' 出现在下标 6 ,所以距离为 abs(8 - 6) = 2
  • 解题 ```javascript /**

    • @解法思路
    • 首先将目标字符c放入到数组targetC中,然后遍历一遍s找出每一位置和字符c位置最小的下标
    • 时间负责度n+nm /
      var shortestToChar = function (s, c) { let res = [] let targetC = [] for (let i = 0, len = s.length; i < len; i++) { s[i] === c && targetC.push(i) } for (let i = 0, len = s.length; i < len; i++) { let tmp = getMin(i, targetC) res.push(tmp) } return res }; function getMin(num, targetC) { let min = Math.abs(targetC[0] - num) for (let i = 0, len = targetC.length; i < len; i++) { Math.abs(targetC[i] - num) < min && (min = Math.abs(targetC[i] - num)) } return min }

/**

  • 双指针写法 */ var shortestToChar = function (s, c) { let res = [] let prev = -10001 for (let i = 0, len = s.length; i < len; i++) {
    1. if (s[i] === c) {
    2. prev = i
    3. }
    4. res[i] = i-prev
    } prev = 10001 for (let len = s.length-1,i=len; i >=0; i—) {
    1. if (s[i] === c) {
    2. prev = i
    3. }
    4. res[i] = Math.min(res[i],prev-i)
    } return res };
  1. <a name="N6a4l"></a>
  2. ### 编程题
  3. 实现symbol polyfill<br />//题解:如果浏览器不支持情况下 写出让代码让浏览器支持symbol
  4. - 学习链接:[https://segmentfault.com/a/1190000015262174#item-9](https://segmentfault.com/a/1190000015262174#item-9)
  5. - [https://gist.github.com/liril-net/4436fb0bdc8f8ddecbdd34bdfa571b14](https://gist.github.com/liril-net/4436fb0bdc8f8ddecbdd34bdfa571b14)
  6. ```javascript
  7. (function () {
  8. var root = this
  9. var generateName = function () {
  10. var postfix = 0
  11. return function (descString) {
  12. postfix++
  13. return `@@${descString}_${postfix}`
  14. }
  15. }
  16. var SymbolPolyfill = function Symbol(description) {
  17. if (this instanceof SymbolPolyfill) {
  18. throw new TypeError('Symbol is not a constructor ')
  19. }
  20. var description = description === undefined ? undefined : String(description)
  21. var symbol = Object.create({
  22. toString: function () {
  23. return this.__name__
  24. },
  25. valueOf: function () {
  26. return this
  27. }
  28. })
  29. Object.defineProperties(symbol, {
  30. __Description__: {
  31. value: description,
  32. writable: false,
  33. enumerable: false,
  34. configurable: false
  35. },
  36. __Name__: {
  37. value: generateName(description),
  38. writable: false,
  39. enumerable: false,
  40. configurable: false
  41. }
  42. })
  43. return symbol
  44. }
  45. var forMap = {}
  46. Object.defineProperties(SymbolPolyfill, {
  47. for: {
  48. value: function (description) {
  49. var decsString = description === undefined ? undefined : String(description)
  50. return forMap[decsString] ? forMap[decsString] : (forMap[decsString] = SymbolPolyfill(decsString))
  51. },
  52. writable: true,
  53. enumerable: false,
  54. configurable: true
  55. },
  56. keyFor: {
  57. value: function (symbol) {
  58. for (var key in forMap) {
  59. if (forMap[key] === symbol) {
  60. return key
  61. }
  62. }
  63. },
  64. writable: true,
  65. enumerable: false,
  66. configurable: true
  67. }
  68. })
  69. root.SymbolPolyfill = SymbolPolyfill
  70. })
  • 特性:
    • 是一种基本数据类型
    • Symbol 值通过 Symbol 函数生成,使用 typeof,结果为 “symbol”
    • Symbol 函数前不能使用 new 命令,否则会报错。这是因为生成的 Symbol 是一个原始类型的值,不是对象。
    • instanceof 的结果为 false
    • Symbol 函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。
    • 如果 Symbol 的参数是一个对象,就会调用该对象的 toString 方法,将其转为字符串,然后才生成一个 Symbol 值。
    • Symbol 函数的参数只是表示对当前 Symbol 值的描述,相同参数的 Symbol 函数的返回值是不相等的。
    • Symbol 值不能与其他类型的值进行运算,会报错。
    • Symbol 值可以显式转为字符串。
    • Symbol 值可以作为标识符,用于对象的属性名,可以保证不会出现同名的属性。
    • Symbol 作为属性名,该属性不会出现在 for…in、for…of 循环中,也不会被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify() 返回。但是,它也不是私有属性,有一个 Object.getOwnPropertySymbols 方法,可以获取指定对象的所有 Symbol 属性名。
    • 如果我们希望使用同一个 Symbol 值,可以使用 Symbol.for。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建并返回一个以该字符串为名称的 Symbol 值。
    • Symbol.keyFor 方法返回一个已登记的 Symbol 类型值的 key。