手写算法
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 是绝对值函数。
示例
输入:s = "loveleetcode", c = "e"
输出:[3,2,1,0,1,0,0,1,2,2,1,0]
解释:字符 'e' 出现在下标 3、5、6 和 11 处(下标从 0 开始计数)。
距下标 0 最近的 'e' 出现在下标 3 ,所以距离为 abs(0 - 3) = 3 。
距下标 1 最近的 'e' 出现在下标 3 ,所以距离为 abs(1 - 3) = 2 。
对于下标 4 ,出现在下标 3 和下标 5 处的 'e' 都离它最近,但距离是一样的 abs(4 - 3) == abs(4 - 5) = 1 。
距下标 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++) {
} prev = 10001 for (let len = s.length-1,i=len; i >=0; i—) {if (s[i] === c) {
prev = i
}
res[i] = i-prev
} return res };if (s[i] === c) {
prev = i
}
res[i] = Math.min(res[i],prev-i)
<a name="N6a4l"></a>
### 编程题
实现symbol polyfill<br />//题解:如果浏览器不支持情况下 写出让代码让浏览器支持symbol
- 学习链接:[https://segmentfault.com/a/1190000015262174#item-9](https://segmentfault.com/a/1190000015262174#item-9)
- [https://gist.github.com/liril-net/4436fb0bdc8f8ddecbdd34bdfa571b14](https://gist.github.com/liril-net/4436fb0bdc8f8ddecbdd34bdfa571b14)
```javascript
(function () {
var root = this
var generateName = function () {
var postfix = 0
return function (descString) {
postfix++
return `@@${descString}_${postfix}`
}
}
var SymbolPolyfill = function Symbol(description) {
if (this instanceof SymbolPolyfill) {
throw new TypeError('Symbol is not a constructor ')
}
var description = description === undefined ? undefined : String(description)
var symbol = Object.create({
toString: function () {
return this.__name__
},
valueOf: function () {
return this
}
})
Object.defineProperties(symbol, {
__Description__: {
value: description,
writable: false,
enumerable: false,
configurable: false
},
__Name__: {
value: generateName(description),
writable: false,
enumerable: false,
configurable: false
}
})
return symbol
}
var forMap = {}
Object.defineProperties(SymbolPolyfill, {
for: {
value: function (description) {
var decsString = description === undefined ? undefined : String(description)
return forMap[decsString] ? forMap[decsString] : (forMap[decsString] = SymbolPolyfill(decsString))
},
writable: true,
enumerable: false,
configurable: true
},
keyFor: {
value: function (symbol) {
for (var key in forMap) {
if (forMap[key] === symbol) {
return key
}
}
},
writable: true,
enumerable: false,
configurable: true
}
})
root.SymbolPolyfill = SymbolPolyfill
})
- 特性:
- 是一种基本数据类型
- 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。