字符串
翻转单词151。
「这个题目归到media难度让我很困惑」 给定一个字符串,逐个翻转字符串中的每个单词。 示例 1:
输入: "the sky is blue" 输出: "blue is sky the"
/**
* @param {string} s
* @return {string}
*/
var reverseWords = function(s) {
let arrs = s.split(' ').filter(i => i);
let res = '';
for (let i = arrs.length - 1; i >= 0; i--) {
res += arrs[i] + (i > 0 ? ' ' : '');
}
return res;
};
相隔为 1 的编辑距离161
给定两个字符串 s 和 t,判断他们的编辑距离是否为 1。
注意:
满足编辑距离等于 1 有三种可能的情形:
往 s 中插入一个字符得到 t 从 s 中删除一个字符得到 t 在 s 中替换一个字符得到 t 示例 1:
输入: s = "ab", t = "acb" 输出: true 解释: 可以将 'c' 插入字符串 s 来得到 t。 示例 2:
输入: s = "cab", t = "ad" 输出: false 解释: 无法通过 1 步操作使 s 变为 t。 示例 3:
输入: s = "1203", t = "1213" 输出: true 解释: 可以将字符串 s 中的 '0' 替换为 '1' 来得到 t。
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isOneEditDistance = function(s, t) {
let difTime;
if (Math.abs(s.length - t.length) > 1) return false;
if (s.length > t.length) {
let temp;
temp = s;
s = t;
t = temp;
}
function hepler(s, t, difTime) {
if (s.length === 0 && t.length === 1) {
if (difTime > 0) {
// console.log(333)
return true;
} else {
return false;
}
}
for (let i = 0 ; i < s.length; i++) {
if (s[i] !== t[i]) {
if ( difTime <= 0) {
// console.log(111)
return false;
} else {
difTime--;
if (s.length !== t.length) {
// console.log(s.substring(i), t.substring(i+1))
return hepler(s.substring(i), t.substring(i+1), 0)
}
}
}
}
if (s.length === t.length && difTime > 0) {
// console.log(222)
return false;
}
if (s.length < t.length && difTime <= 0) {
return false;
}
return true;
}
return hepler(s, t, 1);
};
括号生成22
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 示例:
输入:n = 3 输出:[ "((()))", "(()())", "(())()", "()(())", "()()()" ]
/**
* @param {number} n
* @return {string[]}
*/
var generateParenthesis = function(n) {
if (n === 0) return '';
let res = [];
function generate(left, right, s) {
if (left === n && right === n) {
res.push(s);
return;
}
// 如果左括号没用完,加上一个左括号
if (left < n) {
generate(left + 1, right, s + '(');
}
// 如果右括号小于左括号,可以加一个右括号
if (right < left) {
generate(left, right + 1, s + ')');
}
}
generate(0, 0, '');
return res;
};
动态规划
不同路径63
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。 现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
说明:m 和 n 的值均不超过 100。 输入: [ [0,0,0], [0,1,0], [0,0,0] ] 输出: 2 解释: 3x3 网格的正中间有一个障碍物。 从左上角到右下角一共有 2 条不同的路径:
- 向右 -> 向右 -> 向下 -> 向下
- 向下 -> 向下 -> 向右 -> 向右
/**
* @param {number[][]} obstacleGrid
* @return {number}
*/
var uniquePathsWithObstacles = function(obstacleGrid) {
if (obstacleGrid === null || obstacleGrid.length == 0) {
return 0;
}
let dp = [];
let m = obstacleGrid.length, n = obstacleGrid[0].length;
for (let i = 0; i < m; i++) {
dp[i] = [];
for (let j = 0; j < n; j++) {
dp[i][j] = 0;
}
}
console.log('dp', dp);
for (let i = 0; i < m && obstacleGrid[i][0] === 0; i++) {
dp[i][0] = 1;
}
for (let i = 0; i < n && obstacleGrid[0][i] === 0; i++) {
dp[0][i] = 1;
}
for (let i = 1; i < m ; i++) {
for (let j = 1; j < n; j++) {
if (obstacleGrid[i][j] == 0) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
}
return dp[m - 1][n - 1];
};
Design
LRU 缓存机制
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。
获取数据 get(key) - 如果关键字 (key) 存在于缓存中,则获取关键字的值(总是正数),否则返回 -1。 写入数据 put(key, value) - 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字/值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // 返回 1
cache.put(3, 3); // 该操作会使得关键字 2 作废
cache.get(2); // 返回 -1 (未找到)
cache.put(4, 4); // 该操作会使得关键字 1 作废
cache.get(1); // 返回 -1 (未找到)
cache.get(3); // 返回 3
cache.get(4); // 返回 4
解
class ListNode {
constructor(key, value) {
this.key = key
this.value = value
this.next = null
this.prev = null
}
}
class LRUCache {
constructor(capacity) {
this.capacity = capacity
this.hashTable = {}
this.count = 0
this.dummyHead = new ListNode()
this.dummyTail = new ListNode()
this.dummyHead.next = this.dummyTail
this.dummyTail.prev = this.dummyHead
}
get(key) {
let node = this.hashTable[key]
if (node == null) return -1
this.moveToHead(node)
return node.value
}
put(key, value) {
let node = this.hashTable[key]
if (node == null) {
let newNode = new ListNode(key, value)
this.hashTable[key] = newNode
this.addToHead(newNode)
this.count++
if (this.count > this.capacity) {
this.removeLRUItem()
}
} else {
node.value = value
this.moveToHead(node)
}
}
moveToHead(node) {
this.removeFromList(node)
this.addToHead(node)
}
removeFromList(node) {
let tempForPrev = node.prev
let tempForNext = node.next
tempForPrev.next = tempForNext
tempForNext.prev = tempForPrev
}
addToHead(node) {
node.prev = this.dummyHead
node.next = this.dummyHead.next
this.dummyHead.next.prev = node
this.dummyHead.next = node
}
removeLRUItem() {
let tail = this.popTail()
delete this.hashTable[tail.key]
this.count--
}
popTail() {
let tailItem = this.dummyTail.prev
this.removeFromList(tailItem)
return tailItem
}
}
常数时间插入、删除和随机获取元素 380
设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构。
insert(val):当元素 val 不存在时,向集合中插入该项。 remove(val):元素 val 存在时,从集合中移除该项。 getRandom:随机返回现有集合中的一项。每个元素应该有相同的概率被返回。 示例 :
// 初始化一个空的集合。 RandomizedSet randomSet = new RandomizedSet();
// 向集合中插入 1 。返回 true 表示 1 被成功地插入。 randomSet.insert(1);
// 返回 false ,表示集合中不存在 2 。 randomSet.remove(2);
// 向集合中插入 2 。返回 true 。集合现在包含 [1,2] 。 randomSet.insert(2);
// getRandom 应随机返回 1 或 2 。 randomSet.getRandom();
// 从集合中移除 1 ,返回 true 。集合现在包含 [2] 。 randomSet.remove(1);
// 2 已在集合中,所以返回 false 。 randomSet.insert(2);
// 由于 2 是集合中唯一的数字,getRandom 总是返回 2 。 randomSet.getRandom();
/**
* Initialize your data structure here.
*/
var RandomizedSet = function() {
this.hashTable = {};
this.arrayTable = [];
};
/**
* Inserts a value to the set. Returns true if the set did not already contain the specified element.
* @param {number} val
* @return {boolean}
*/
RandomizedSet.prototype.insert = function(val) {
if (this.hashTable.hasOwnProperty(val)) {
return false;
}
this.hashTable[val] = this.arrayTable.length;
this.arrayTable.push(val);
return true;
};
/**
* Removes a value from the set. Returns true if the set contained the specified element.
* @param {number} val
* @return {boolean}
*/
RandomizedSet.prototype.remove = function(val) {
if (this.hashTable.hasOwnProperty(val)) {
if (this.hashTable[val] !== this.arrayTable.length - 1) {
const index = this.hashTable[val];
const lastVal = this.arrayTable[this.arrayTable.length - 1];
this.arrayTable[index] = lastVal;
this.hashTable[lastVal] = index;
}
this.arrayTable.splice(this.arrayTable.length - 1, 1);
delete this.hashTable[val];
return true;
}
return false;
};
/**
* Get a random element from the set.
* @return {number}
*/
RandomizedSet.prototype.getRandom = function() {
const length = this.arrayTable.length;
const randomKey = Math.floor(Math.random() * length);
return this.arrayTable[randomKey];
};