前言
粉刷房子_简单
普通的动态方程dp[i] = dp[i-1] + xx不满足条件
如:[[4,5,13],[1,100,1000]]
所以对于每个粉刷的值由其本身和上个房子的两种颜色决定。
假如有一排房子,共 n
个,每个房子可以被粉刷成红色、蓝色或者绿色这三种颜色中的一种,你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同。
当然,因为市场上不同颜色油漆的价格不同,所以房子粉刷成不同颜色的花费成本也是不同的。每个房子粉刷成不同颜色的花费是以一个 n x 3
的矩阵来表示的。
例如,costs[0][0] 表示第 0 号房子粉刷成红色的成本花费;costs[1][2] 表示第 1
号房子粉刷成绿色的花费,以此类推。请你计算出粉刷完所有房子最少的花费成本。
注意:
所有花费均为正整数。
示例:
输入: [[17,2,17],[16,16,5],[14,3,19]] 输出: 10 解释: 将 0 号房子粉刷成蓝色,1
号房子粉刷成绿色,2 号房子粉刷成蓝色。
最少花费: 2 + 5 + 3 = 10。
/**
* @param {number[][]} costs
* @return {number}
*/
var minCost = function (costs) {
let len = costs.length
if (len <= 0) return costs
let dp = Array.from(new Array(len).fill(0), () => new Array(3).fill(0))
dp[0] = costs[0]
for (let i = 1; i < len; i++) {
dp[i][0] = costs[i][0] + Math.min(dp[i - 1][1], dp[i - 1][2])
dp[i][1] = costs[i][1] + Math.min(dp[i - 1][0], dp[i - 1][2])
dp[i][2] = costs[i][2] + Math.min(dp[i - 1][0], dp[i - 1][1])
}
// return Math.min.call(null, dp[len - 1])
return Math.min(...dp[len - 1])
};
比特位计数_中等
给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。
示例 1:
输入: 2 输出: [0,1,1] 示例 2:
输入: 5 输出: [0,1,1,2,1,2]
var countBits = function (num) {
let dp = []
dp[0] = 0
for (let i = 1; i <= num; i++) {
if(i%2 === 0){
dp[i] = dp[i/2]
}else{
dp[i] = dp[i-1] + 1
}
}
return dp
};
单词拆分_中等
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
说明:拆分时可以重复使用字典中的单词。 你可以假设字典中没有重复的单词。
示例 1: 输入: s = “leetcode”, wordDict =[“leet”, “code”] 输出: true 解释: 返回 true 因为 “leetcode” 可以被拆分成 “leet code”。
示例 2: 输入: s = “applepenapple”, wordDict = [“apple”, “pen”] 输出:true 解释: 返回 true 因为 “applepenapple” 可以被拆分成 “apple pen apple”。
注意你可以重复使用字典中的单词。 示例 3: 输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”] 输出: false
/**
* @param {string} s
* @param {string[]} wordDict
* @return {boolean}
*/
var wordBreak = function (s, wordDict) {
let len = s.length
let arr = new Array(len + 1).fill(false)
arr[0] = true
for (let i = 1; i <= len; i++) {
for (let j = 0;j < i; j++) {
if(arr[j] && wordDict.includes(s.slice(j,i))){
arr[i]=true
}
}
}
return arr[len]
};
编辑距离_困难
给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
插入一个字符 删除一个字符 替换一个字符 示例 1:
输入: word1 = “horse”, word2 = “ros” 输出: 3 解释: horse -> rorse (将 ‘h’
替换为 ‘r’) rorse -> rose (删除 ‘r’) rose -> ros (删除 ‘e’) 示例 2:输入: word1 = “intention”, word2 = “execution” 输出: 5 解释: intention ->
inention (删除 ‘t’) inention -> enention (将 ‘i’ 替换为 ‘e’) enention ->
exention (将 ‘n’ 替换为 ‘x’) exention -> exection (将 ‘n’ 替换为 ‘c’) exection
-> execution (插入 ‘u’)
var minDistance = function (word1, word2) {
let str1 = ' ' + word1;
let str2 = ' ' + word2;
const n = str1.length, m = str2.length;
if (n * m === 0) {
return n + m;
}
let dp = [...new Array(n)].map(() => new Array(m));
for (let i = 0; i < n; i++) {
dp[i][0] = i;
}
for (let j = 0; j < m; j++) {
dp[0][j] = j;
}
for (let i = 1; i < n; i++) {
for (let j = 1; j < m; j++) {
if (str1[i] === str2[j]) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1
}
}
}
return dp[n - 1][m - 1]
}