最长公共子序列
问题描述: 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
- 例如,
"ace"是"abcde"的子序列,但"aec"不是"abcde"的子序列。
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。(by leetcode 剑指 Offer II 095)
示例 :
输入:text1 = "abcde", text2 = "ace"
输出:3
解释:最长公共子序列是 "ace" ,它的长度为 3 。
思路-动态规划:
① 横轴是text1,纵轴是text2,指针在横轴和纵轴上往后移动,当纵轴与横轴值相等,那么就加上斜轴当前位置向上一个位置的值+1,若不相等,则取上方或者左边相对较大的值。
② 由于要处理前面的值,为了方便,我们给格子第一行和第一列都填上0.
/**
* @param {string} text1
* @param {string} text2
* @return {number}
*/
var longestCommonSubsequence = function(text1, text2) {
let len1=text1.length,len2=text2.length;
let d=new Array(len1+1).fill(0).map(item=>new Array(len2+1).fill(0));
for(let i=1;i<=len1;i++){
for(let j=1;j<=len2;j++){
if(text1.charAt(i-1)==text2.charAt(j-1)){
d[i][j]=d[i-1][j-1]+1
}else{
d[i][j]=Math.max(d[i-1][j],d[i][j-1])
}
}
}
return d[len1][len2]
};
买卖股票的最佳时机
问题描述: 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。(by leetcode 121)
示例 :
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
思路:
后面的值减前面的值的最大差值便是我们要输出的值,从前往后走的时候:
1.我们需要计算差值,与之前最大的差值比较。
2.找到最小值,用于后面计算差值。
3.遍历到最后,返回最大的差值。
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(arr) {
let minPrice=arr[0];
let max=0;
for(let i=0;i<arr.length;i++){
if(arr[i]<minPrice){
minPrice=arr[i]
}
if(arr[i]-minPrice>max){
max=arr[i]-minPrice
}
}
return max
}
使用最小花费爬楼梯
问题描述: 数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i](下标从 0 开始)。
每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯。
请你找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 0 或 1 的元素作为初始阶梯。(by leetcode746)
示例 :
输入:cost = [10, 15, 20]
输出:15
解释:最低花费是从 cost[1] 开始,然后走两步即可到阶梯顶,一共花费 15 。
思路-动态规划:
计算到达每一个节点需要的体力值(这里需要比较大小来确定从前一个还是前两个位置跳过来)。问题就变成了求最后一个节点的后一个节点需要的体力值。
/**
* @param {number[]} cost
* @return {number}
*/
var minCostClimbingStairs = function(cost) {
let arr=[0,0]//往第一个节点跳需要的体力值
for(let i=2;i<=cost.length;i++){
arr[i]=Math.min(arr[i-2]+cost[i-2],arr[i-1]+cost[i-1])
}
return arr[arr.length-1]
};
翻转二叉树
问题描述: 翻转一棵二叉树。(by leetcode 226)
示例:
输入:
4
/ \
2 7
/ \ / \
1 3 6 9
输出:
4
/ \
7 2
/ \ / \
9 6 3 1
思路:
采用递归的方式,交换左右子树(子树是交换好的)
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {TreeNode}
*/
var invertTree = function(root) {
if(root==null) return root;
let left=invertTree(root.left);
let right=invertTree(root.right);
root.left=right;
root.right=left;
return root;
};