目录
最大连续子序列和dp[i] = (dp[i-1]+a[i], a[i]);
股票的最大价值:交易一次:1.更新最低点,2.更新利润 maxProfit = prices[i] - minPrice;
股票的最大价值2:可以交易多次。1.更新利润。maxProfit += prices[i] - prices[i-1];
39.组合总和:给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 tar
90. 子集 II给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
二分
有序数组翻转后找值
class Solution {
public:
int search(int A[], int n, int target){
int begin = 0;
int end = n-1;
while(begin <= end){
int mid = (begin + end)/2;
//判断mid是否为target,如果是,直接返回,如果不是,再判断target是在前半段还是后半段
if(A[mid] == target){
return mid;
}
//如果前半段有序
if(A[begin] <= A[mid]){
//判断target是否在前半段,如果在,则继续遍历前半段,
//如果不在,则继续遍历无序的后半段
if(A[begin] <= target && target < A[mid])
end = mid - 1;
else
begin = mid + 1;
}
//如果后半段有序
else{
//判断target是否在后半段,如果在,继续遍历后半段,
//如果不在后半段,则继续遍历无序的前半段
if(A[mid] < target && target <= A[end])
begin = mid + 1;
else
end = mid - 1;
}
}
return -1;
}
}
动态规划
最小编辑距离
int minDistance(string word1, string word2) {
int n1 = word1.size();
int n2 = word2.size();
vector<vector<int>> dp(n1+1,vector<int>(n2+1));
//第一列
for(int i=0;i<=n1;++i)
dp[i][0]=i;
//第一行
for(int j=0;j<=n2;++j)
dp[0][j]=j;
for(int i=1;i<=n1;++i)
for(int j=1;j<=n2;++j){
if(word1[i-1]==word2[j-1])
dp[i][j] = dp[i-1][j-1];
else
dp[i][j] = min(min(dp[i-1][j-1],dp[i][j-1]),dp[i-1][j])+1;
}
return dp[n1][n2];
}
最大连续子序列和dp[i] = (dp[i-1]+a[i], a[i]);
#include <iostream>
using namespace std;
int main(){
int a[100], n;
cin >> n;
for(int i = 1; i <= n; i++){
cin >> a[i];
}
int dp[1000];
int maxNum = INT_MIN;
dp[0] = 0;
for(int i = 1; i <= n; i++){
dp[i] = max(dp[i - 1] + a[i], a[i]);///状态转移方程,表示以第i个数结尾的连续子序列的
最大和
maxNum = max(maxNum, dp[i];
}
cout << maxNum << endl;
return 0;
}
最长上升子序列
dp[i]保存的是以nums[i]结尾的最长子序列,不是前i个元素中的最长子序列,所以还要用一个maxLIS来记录最长的
class Solution {
public:
int lengthOfLIS(vector<int> &nums) {
if (nums.size() == 0)
return 0;
vector<int> dp(nums.size(), 0);
dp[0] = 1;
int maxLIS = 1;
for (int i = 1; i < nums.size(); i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j] && dp[i] < dp[j] + 1)
dp[i] = dp[j] + 1;
maxLIS = max(dp[i], maxLIS);
}
}
return maxLIS;
}
};
最长公共子序列
int longestSubsequen(string x, string y) {
int **dp = new int*[x.size() + 1];
for (int i = 0; i < x.size(); i++) {
dp[i] = new int[y.size() + 1];
}
for (int i = 0; i <= x.size(); i++) dp[i][0] = 0;
for (int i = 0; i <= y.size(); i++) dp[0][i] = 0;
for (int i = 1; i <= x.size(); i++) {
for (int j = 1; j <= y.size(); j++) {
if (x[i] == y[j]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
else {
dp[i][j] = dp[i - 1][j] > dp[i][j - 1] ? dp[i - 1][j] : dp[i][j - 1];
}
}
}
return dp[x.size()][y.size()];
}
最长公共子串
int longestSubstring(string x, string y) {
vector<vector<int> > f(x.size() + 1, vector<int>(y.size() + 1, 0));
int max = -1;
for (int i = 1; i <= x.size(); i++) {
for (int j = 1; j <= y.size(); j++) {
if (x[i - 1] != y[j - 1])
f[i][j] = 0;
else if (x[i - 1] == y[j - 1])
f[i][j] = f[i - 1][j - 1] + 1;
if (max < f[i][j]) {
max = f[i][j];
}
}
}
return max;
}
字符串匹配
class Solution {
public:
vector<vector<int>>f;
int n, m;
bool isMatch(string s, string p) {
n = s.size();
m = p.size();
// 为什么不是n,m 因为考虑到s,p都为空的情况
f = vector<vector<int>>(n + 1, vector<int>(m + 1, -1));
return dp(0, 0, s, p);
}
bool dp(int x, int y, string &s, string &p)
{
//利用到的f[x][y] 有值说明已经计算过,直接返回不需要再去递归。利用到已经计算到的值,截枝不让重复递归
if (f[x][y] != -1) return f[x][y];
if (y == m)
return f[x][y] = x == n;
bool first_match = x < n && (s[x] == p[y] || p[y] == '.');
bool ans;
if (y + 1 < m && p[y + 1] == '*')
{
ans = dp(x, y + 2, s, p) || first_match && dp(x + 1, y, s, p);
}
else
ans = first_match && dp(x + 1, y + 1, s, p);
return f[x][y] = ans;
}
};
最大无重复子串
int fun(vector<int> arr){
unordered_map<int> hash;
for(int i = 0, j = 0; i < arr.size(); i++){
hash[s[i]]++;
while(hash[s[i]] > 1){
hash[s[j++]--];
}
res = max(res, i-j+1);
}
return res;
}
最长回文子串
string ishuiwen(string s){
string res;
for(inti = 0; i < s.size(); i++){
string left = helper(s, i, i+1);
string right = helper(s, i, i);
if(left.size() > res.size())
res = left;
if(right.size() > res.size())
res = right;
}
return res;
}
string helper(string s, int left, int right){
while(left >= 0 && right < s.size() && s[left] == s[right]){
left--;
right++;
}
return s.substr(left+1, right - left - 1);
}
股票的最大价值:交易一次:1.更新最低点,2.更新利润 maxProfit = prices[i] - minPrice;
int maxProfit(vector<int>& prices) {
int minPrice = INT_MAX;
int maxProfit = 0;
for(int i = 0; i < prices.size(); i++){
if(prices[i] < minPrice)
minPrice = prices[i];
else if(prices[i] - minPrice > maxProfit)
maxProfit = prices[i] - minPrice;
}
return maxProfit;
}
股票的最大价值2:可以交易多次。1.更新利润。maxProfit += prices[i] - prices[i-1];
int maxProfit(vector<int>& prices) {
int sum = 0;
for(int i = 1; i < prices.size(); i++){
if(prices[i] > prices[i-1]){
sum = sum + prices[i] - prices[i-1];
}
}
return sum;
}
排序
快排
#include<iostream>
using namespace std;
int getIndex(int arr[], int low, int high){
int key = arr[low];
while(low < high){
while(low < high && arr[high] >= key){
high--;
}
if(low < high)
arr[low] = arr[high];
while(low < high && arr[low] <= key)
low++;
if(low < high)
arr[high] = arr[low];
}
arr[low] = key;
return low;
}
void quicksort(int arr[], int low, int high){
if(low < high){
int index = getIndex(arr,low, high);
quicksort(arr, low, index - 1);
quicksort(arr, index+1, high);
}
}
int main(){
int a[] = {1,2,4,6,4,2,1};
quicksort(a, 0, 6);
for(int i = 0; i < 6; i++){
cout<< a[i];
}
return 0;
}