思路+解法
暴力 O(n^2)
排序+双指针 O(nlogn)
class Solution {
public:
vector twoSum(vector& nums, int target) {
int size = nums.size();
vector> vec(size, vector(2));
for(int i = 0; i < size; i++){
vec[i][0] = nums[i];
vec[i][1] = i;
}
sort(vec.begin(), vec.end());
int l = 0, r = size - 1;
while(l < r){
if(vec[l][0] + vec[r][0] == target){
return vector{vec[l][1], vec[r][1]};
}
else if(vec[l][0] + vec[r][0] > target){
r--;
}
else if(vec[l][0] + vec[r][0] < target){
l++;
}
}
return vector{};
}
};
哈希表 O(n)
class Solution {
public:
vector twoSum(vector& nums, int target) {
unordered_map m;
vector ans;
for(int i = 0; i < nums.size(); i++){
if(m.find(target - nums[i]) != m.end()){
return vector{m[target - nums[i]], i};
}
m[nums[i]] = i;
}
return ans;
}
};
一点收获
思路+解法
排序+双指针 O(n^2)
class Solution {
public:
vector> threeSum(vector& nums) {
int size = nums.size();
sort(nums.begin(), nums.end());
vector> ans;
for(int i = 0; i < size; i++){
//第一个元素大于0的剪枝很巧妙
if(nums[i] > 0) return ans;
//去重
if(i > 0 && nums[i] == nums[i-1]) continue;
int j = i + 1, k = size - 1;
while(j < k){
if(nums[j] + nums[k] == -nums[i]){
ans.push_back({nums[i], nums[j], nums[k]});
j++;
k--;
//去重
while(j < k && nums[j] == nums[j - 1]) j++;
while(j < k && nums[k] == nums[k + 1]) k--;
}
else if(nums[j] + nums[k] > -nums[i]){
k--;
}
else if(nums[j] + nums[k] < -nums[i]){
j++;
}
}
}
return ans;
}
};
思路+解法
排序+双指针 O(n^3)
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
vector<vector<int>> ans;
int size = nums.size();
for(int i = 0; i < size; i++){
if(i > 0 && nums[i] == nums[i-1]) continue;
for(int j = i + 1; j < size; j++){
if(j > i + 1 && nums[j] == nums[j-1]) continue;
int l = j + 1, r = size - 1;
while(l < r){
//合超int范围
if((long long)nums[i] + nums[j] + nums[l] + nums[r] == target){
ans.push_back({nums[i], nums[j], nums[l], nums[r]});
l++;
r--;
while(l < r && nums[l] == nums[l - 1]) l++;
while(l < r && nums[r] == nums[r + 1]) r--;
}
else if((long long)nums[i] + nums[j] + nums[l] + nums[r] > target){
r--;
}
else if((long long)nums[i] + nums[j] + nums[l] + nums[r] < target){
l++;
}
}
}
}
return ans;
}
};
一点剪枝优化(140ms->8ms)
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
vector<vector<int>> ans;
int size = nums.size();
for(int i = 0; i < size - 3; i++){
//剪枝
if ((long long)nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) break;
if ((long long)nums[i] + nums[size - 3] + nums[size - 2] + nums[size - 1] < target) continue;
//去重
if(i > 0 && nums[i] == nums[i-1]) continue;
for(int j = i + 1; j < size - 2; j++){
//剪枝
if ((long long)nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) break;
if ((long long)nums[i] + nums[j] + nums[size - 2] + nums[size - 1] < target) continue;
//去重
if(j > i + 1 && nums[j] == nums[j-1]) continue;
int l = j + 1, r = size - 1;
while(l < r){
//合超int范围
if((long long)nums[i] + nums[j] + nums[l] + nums[r] == target){
ans.push_back({nums[i], nums[j], nums[l], nums[r]});
l++;
r--;
while(l < r && nums[l] == nums[l - 1]) l++;
while(l < r && nums[r] == nums[r + 1]) r--;
}
else if((long long)nums[i] + nums[j] + nums[l] + nums[r] > target){
r--;
}
else if((long long)nums[i] + nums[j] + nums[l] + nums[r] < target){
l++;
}
}
}
}
return ans;
}
};
思路+解法
哈希表 O(n^2)
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int ans = 0;
unordered_map<int, int> m;
for(auto x : nums1){
for(auto y : nums2){
m[x+y]++;
}
}
for(auto x : nums3){
for(auto y : nums4){
if(m.find(-(x + y)) != m.end()) ans += m[-(x + y)];
}
}
return ans;
}
};
思路+解法
排序+双指针 O(n^2)
class Solution {
public:
int threeSumClosest(vector& nums, int target) {
sort(nums.begin(), nums.end());
int size = nums.size();
int ans = 100000;
for(int i = 0; i < size; i++){
//剪枝
if(i > 0 && nums[i] == nums[i - 1]) continue;
int l = i + 1, r = size - 1;
while(l < r){
if(nums[i] + nums[l] + nums[r] == target){
return target;
}
else{
//计算当前值是否靠近
if(abs(nums[i] + nums[l] + nums[r] - target) < abs(ans - target)){
ans = nums[i] + nums[l] + nums[r];
}
//双指针移动
if(nums[i] + nums[l] + nums[r] > target) {
r--;
//剪枝
while(l < r && nums[r] == nums[r + 1]) r--;
}
else if(nums[i] + nums[l] + nums[r] < target){
l++;
//剪枝
while(l < r && nums[l] == nums[l-1]) l++;
}
}
}
}
return ans;
}
};
一点收获:
思路+解法
双指针滑动窗口 O(n)
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int ans = nums[0];
int l = 0, r = 1;
int now = nums[0];
while(r < nums.size()){
now += nums[r];
while(l < r && now < nums[r]){
now -= nums[l];
l++;
}
r++;
ans = max(now, ans);
}
return ans;
}
};
动态规划 O(n)
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int ans = nums[0];
vector<int> dp(nums.size(), 0);
dp[0] = nums[0];
for(int i = 1; i < nums.size(); i++){
dp[i] = max(nums[i], dp[i - 1] + nums[i]);
ans = max(dp[i], ans);
}
return ans;
}
};
分治法 O(nlogn)
前缀和 O(n)
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int ans = nums[0];
int minPrefix = 0;
int sum = 0;
for(int i = 0; i < nums.size(); i++){
sum += nums[i];
ans = max(ans, sum - minPrefix);
minPrefix = min(minPrefix, sum);
}
return ans;
}
};
一点收获
思路+解法
排序 O*(*nlognlogm)
class Solution {
public:
static bool cmp(string a, string b){
return a + b > b + a;
}
string largestNumber(vector<int>& nums) {
vector<string> strs;
for(int i = 0; i < nums.size(); i++){
strs.push_back(to_string(nums[i]));
}
sort(strs.begin(), strs.end(), cmp);
string ans = "";
for(string s : strs){
ans += s;
}
if(ans[0] == '0') return "0";
return ans;
}
};
一点收获
思路+解法:
比较余数 O(l) l是答案的长度
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
string ans ="";
if((long long)numerator * denominator < 0) ans += '-';
long long a = abs(numerator);
long long b = abs(denominator);
ans += to_string(a / b);
a = a % b;
if(a != 0) ans += ".";
unordered_map<long long, int> m;
int loc = ans.size(); //小数的第几位
m[a] = loc++;
while(a > 0){
a *= 10;
//得到的数
long long x = a / b;
ans += to_string(x);
//这一步的余数
a -= x * b;
if(m.find(a) != m.end()){
ans.insert(ans.begin() + m[a], '(');
ans += ')';
return ans;
}
m[a] = loc++;
}
return ans;
}
};
一点收获
思路+解法
动态规划 O(n^2)
class Solution {
public:
vector<int> largestDivisibleSubset(vector<int>& nums) {
sort(nums.begin(), nums.end());
int size = nums.size();
vector<int> ans;
vector<int> dp(size, 1);
//当前位置的前一个元素
vector<int> pre(size, -1);
//整除子集的最大长度
int maxlen = 1;
int maxloc = 0;
for(int i = 0; i < nums.size(); i++){
for(int j = 0; j < i; j++){
if(nums[i] % nums[j] == 0){
if(dp[j] + 1 > dp[i]){
dp[i] = dp[j] + 1;
pre[i] = j;
}
}
}
if(dp[i] > maxlen){
maxlen = dp[i];
maxloc = i;
}
}
ans.push_back(nums[maxloc]);
int loc = pre[maxloc];
//回溯找答案
while(loc != -1){
ans.push_back(nums[loc]);
loc = pre[loc];
}
return ans;
}
};
思路+解法
埃氏筛法 O(nloglogn)
class Solution {
private:
vector<int> is_prime = vector<int>(101, true);
public:
int sieve(int n){
int p = 0;
is_prime[0] = is_prime[1] = false;
for(int i = 2; i <= n; i++){
if(is_prime[i]){
p++;
for(int j = i * 2; j <= n; j += i){
is_prime[j] = false;
}
}
}
return p;
}
int numPrimeArrangements(int n) {
int k1 = sieve(n);
int k2 = n - k1;
long ans = 1;
for(int i = 2; i <= k1; i++){
ans = (ans * i) % 1000000007;
}
for(int i = 2; i <= k2; i++){
ans = (ans * i) % 1000000007;
}
return ans;
}
};
思路+解法:
双指针 O(n)
class Solution {
public:
bool isPalindrome(string & s, int l, int r){
while(l < r){
if(s[l] != s[r]) return false;
l++ ,r--;
};
return true;
}
bool validPalindrome(string s) {
int size = s.size();
int l = 0, r = size - 1;
int cnt = 0;
while(l < r){
if(s[l] != s[r]){
return isPalindrome(s, l + 1, r) || isPalindrome(s, l, r - 1);
}
l++ ,r--;
}
return true;
}
};
一点收获:
思路+解法:
快慢指针翻转后半部分后比较 O(n)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(head->next == nullptr) return true;
//快慢指针找到前半部分的结尾
ListNode* slow = head;
ListNode* fast = head;
while(fast->next != nullptr && fast->next->next != nullptr){
fast = fast->next->next;
slow = slow->next;
}
//翻转后半部分
ListNode* pre = slow->next;
ListNode* cur = slow->next->next;
pre->next = nullptr; //!
while(cur != nullptr){
ListNode* temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
//回文比较
ListNode* firstHalfHead = head;
ListNode* secondHalfHead = pre;
while(secondHalfHead != nullptr){
if(firstHalfHead->val != secondHalfHead->val) return false;
firstHalfHead = firstHalfHead->next;
secondHalfHead = secondHalfHead->next;
}
return true;
}
};
翻转前半部分* O(n)
一点收获:
思路+解法:
只翻转一半数字 O(logn)
class Solution {
public:
bool isPalindrome(int x) {
if(x < 0) return false;
if(x == 0) return true;
if(x % 10 == 0) return false;
int rev_num = 0;
while(x > rev_num){
rev_num = rev_num * 10 + x % 10;
x /= 10;
}
return x == rev_num || x == rev_num / 10;
}
};
思路+解法
动态规划 O(n^2)
class Solution {
public:
string longestPalindrome(string s) {
int n = s.size();
//dp数组含义:从i到j的字符串是否为回文子串
vector<vector<bool>> dp(n, vector<bool>(n, false));
for(int i = 0; i < n; i++){
dp[i][i] = 0;
}
int max_len = 1;
int begin = 0;
//画表看遍历顺序
for(int i = n - 2; i >= 0; i--){
for(int j = i + 1; j < n; j++){
if(s[i] == s[j]){
if(j - i <= 2){
dp[i][j] = true;
}
else{
if(dp[i + 1][j - 1]) dp[i][j] = true;
}
}
if(dp[i][j]){
if(j - i + 1 > max_len){
max_len = j - i + 1;
begin = i;
}
}
}
}
return s.substr(begin, max_len);
}
};
中心扩展 O(n^2)
class Solution {
public:
int n = 0;
int extend(string& s, int left, int right){
while(right < n && left >= 0 && s[left] == s[right]){
left--;
right++;
}
return right - left - 1;
}
string longestPalindrome(string s) {
n = s.size();
int max_len = 1;
int start = 0;
for(int i = 0; i < n; i++){
int len1 ;
len1 = extend(s, i, i);
int len2;
len2 = extend(s, i, i + 1);
int len = max(len1, len2);
if(len > max_len){
max_len = len;
start = i - (len - 1) / 2;
}
}
return s.substr(start, max_len);
}
};
马拉车
思路+解法
动态规划 O(n^2)
class Solution {
public:
int longestPalindromeSubseq(string s) {
int n = s.size();
int ans = 1;
vector<vector<int>> dp(n, vector<int>(n, 0));
for(int i = 0; i < n; i++) dp[i][i] = 1;
for(int i = n - 2; i >= 0; i--){
for(int j = i + 1; j < n; j++){
if(s[i] == s[j]){
dp[i][j] = dp[i + 1][j - 1] + 2;
}
else{
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
}
}
}
return dp[0][n - 1];
}
};
思路+解法
构造回文数 O(W1/4∗logW)
class Solution {
public:
bool isPalindrome(long long x){
if(x % 10 == 0) return false;
long long rev_num = 0;
while(x > rev_num){
rev_num = rev_num * 10 + x % 10;
x /= 10;
}
return x == rev_num || x == rev_num / 10;
}
int superpalindromesInRange(string left, string right) {
int ans = 0;
long long l = stol(left);
long long r = stol(right);
//ABBA
for(int i = 1; i < 100000; i++){
string s1 = to_string(i);
string s2 = s1;
reverse(s2.begin(), s2.end());
string s = s1 + s2;
long m = stol(s);
m *= m;
if(m > r) break;
if(m >= l && isPalindrome(m)){
ans++;
}
}
//ABA
for(int i = 1; i < 100000; i++){
string s1 = to_string(i);
string s2 = s1;
reverse(s2.begin(), s2.end());
string s = s1.append(s2.begin() + 1, s2.end());
long m = stol(s);
m *= m;
if(m > r) break;
if(m >= l && isPalindrome(m)){
ans++;
}
}
return ans;
}
};
思路+解法:
DFS递归 O(n)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool dfs(TreeNode* node, int sum, int tar){
if(!node) return false;
sum += node->val;
if(!node->left && !node->right){
if(sum == tar) return true;
else return false;
}
return dfs(node->left, sum, tar) || dfs(node->right, sum, tar);
}
bool hasPathSum(TreeNode* root, int targetSum) {
return dfs(root, 0, targetSum);
}
};
思路+解法:
DFS O(n)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int target;
vector<vector<int>> ans;
vector<int> path;
void dfs(TreeNode* node, int sum){
if(!node->left && !node->right && sum == target){
ans.push_back(path);
return;
}
if(node->left){
path.push_back(node->left->val);
dfs(node->left, sum + node->left->val);
path.pop_back();
}
if(node->right){
path.push_back(node->right->val);
dfs(node->right, sum + node->right->val);
path.pop_back();
}
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
if(!root) return ans;
target = targetSum;
ans.clear();
path.clear();
path.push_back(root->val);
dfs(root, root->val);
return ans;
}
};
思路+解法:
DFS后序遍历 O(n)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int ans = INT_MIN;
//后序遍历
//每个节点拥有自己的最大值,可以同时拥有左右节点
//但是给父节点返回的只能为一条路径
int dfs(TreeNode* node){
if(!node) return 0;
int left_sum = dfs(node->left);
int right_sum = dfs(node->right);
int node_max = node->val;
node_max += left_sum > 0? left_sum : 0;
node_max += right_sum > 0? right_sum : 0;
ans = max(node_max, ans);
return max(node->val, max(node->val + left_sum, node->val + right_sum));
}
int maxPathSum(TreeNode* root) {
dfs(root);
return ans;
}
};
思路+解法:
二分模板 O(logn)
class Solution {
public:
int search(vector<int>& nums, int target) {
int l = 0, r = nums.size() - 1;
while(l <= r){
int mid = (r - l) / 2 + l;
if(nums[mid] == target) return mid;
else if(nums[mid] > target){
r = mid - 1;
}else if(nums[mid] < target){
l = mid + 1;
}
}
return -1;
}
};
解法+思路:
二分查找 O(logn)
class Solution {
public:
int findMin(vector<int>& nums) {
int l = 0, r = nums.size() - 1;
while(l <= r){
int mid = (r - l) / 2 + l;
if((mid == 0 || nums[mid] < nums[mid - 1]) &&(mid == nums.size() - 1 || nums[mid] < nums[mid + 1])) return nums[mid];
else if(nums[mid] > nums[r]){
l = mid + 1;
}
else {
r = mid - 1;
}
}
return -1;
}
};
思路+解法:
二分答案 O(logn)
class Solution {
public:
int minEatingSpeed(vector<int>& piles, int h) {
int l = 1, r = pow(10 ,9);
int ans = 1;
while(l <= r){
int mid = (r - l)/2 + l;
int sum = 0;
for(int i = 0; i < piles.size(); i++){
sum += piles[i] / mid;
if(piles[i] % mid != 0) sum++;
}
if(sum > h){
l = mid + 1;
}
else if(sum <= h){
ans = mid;
r = mid - 1;
}
}
return ans;
}
};
思路+解法:
二分答案 O(logn)
class Solution {
public:
int mySqrt(int x) {
int l = 0, r = x;
int ans = 0;
while(l <= r){
int mid = (r - l) / 2 + l;
if((long long)mid * mid <= x){
l = mid + 1;
ans = mid;
}
else{
r = mid - 1;
}
}
return ans;
}
};
思路+解法:
二分查找 O(logn)
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int l = 0, r = nums.size() - 1;
while(l <= r){
int mid = (r - l) / 2 + l;
if((mid == 0 || nums[mid] > nums[mid - 1]) &&(mid == nums.size() - 1 || nums[mid] > nums[mid + 1])) return mid;
if(mid == 0 || nums[mid] > nums[mid - 1] ){
l = mid + 1;
}
else if(nums[mid] < nums[mid - 1]){
r = mid - 1;
}
}
return -1;
}
};
思路+解法
二分答案 O(nlog(sum - max_num))
class Solution {
public:
bool cal(vector<int>& nums, int max_sum, int m){
int _m = 0;
int temp_sum = 0;
for(int x : nums){
if(temp_sum + x > max_sum){
_m++;
temp_sum = x;
}
else temp_sum += x;
}
if(temp_sum > 0) _m++;
return _m <= m;
}
int splitArray(vector<int>& nums, int m) {
int sum = 0;
int max_num = INT_MIN;
for(int x : nums) {
sum += x;
max_num = max(max_num, x);
}
//二分区间为最大的元素到所有元素的和
int l = max_num, r = sum;
int ans = 0;
while(l <= r){
int mid = (r - l) / 2 + l;
if(cal(nums, mid, m)){
ans = mid;
r = mid - 1;
}
else{
l = mid + 1;
}
}
return ans;
}
};
思路+解法:
O()
思路+解法:
O()
思路+解法:
O()
思路+解法:
异或 O(n)
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ans = 0;
for(int& x : nums) ans ^= x;
return ans;
}
};
思路+解法:
辅助栈 O(1) O(n)
class MinStack {
public:
stack<int> s;
stack<int> assist_s;
MinStack() {
}
void push(int val) {
s.push(val);
if(assist_s.empty() || assist_s.top() > val) assist_s.push(val);
else if(assist_s.top() <= val) assist_s.push(assist_s.top());
}
void pop() {
s.pop();
assist_s.pop();
}
int top() {
return s.top();
}
int getMin() {
return assist_s.top();
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(val);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
数组中存的是差值 O(1)空间复杂度
class MinStack {
public:
stack<long long> s;
long long min_value;
MinStack() {
}
void push(int val) {
if(s.empty()){
min_value = val;
s.push(0);
}else{
s.push(val - min_value);
if(val - min_value < 0){
min_value = val;
}
}
}
void pop() {
if(s.top() > 0){
s.pop();
}else{
min_value = min_value - s.top();
s.pop();
}
}
int top() {
if(s.top() > 0){
return min_value + s.top();
}else{
return min_value;
}
}
int getMin() {
return min_value;
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(val);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
思路+解法:
Trie树
const int N = 1e5+50;
bool isEnd[N];
int son[N][26];
int idx = 0;
class Trie {
public:
/** Initialize your data structure here. */
Trie() {
memset(isEnd,false, sizeof(isEnd));
memset(son, 0, sizeof(son));
}
/** Inserts a word into the trie. */
void insert(string word) {
int p = 0;
for(auto x: word){
int u = x - 'a';
if(!son[p][u]){
son[p][u] = ++idx; //默认节点是0,所以前置++
}
p = son[p][u]; //移动到下一个节点编号
}
isEnd[p] = true; //标记结尾
}
/** Returns if the word is in the trie. */
bool search(string word) {
int p = 0;
for(auto x: word){
int u = x - 'a';
if(!son[p][u]){
return false;
}
p = son[p][u];
}
return isEnd[p];
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
int p = 0;
for(auto x : prefix){
int u = x - 'a';
if(!son[p][u]){
return false;
}
p = son[p][u];
}
return true;
}
};
/**
* Your Trie object will be instantiated and called as such:
* Trie* obj = new Trie();
* obj->insert(word);
* bool param_2 = obj->search(word);
* bool param_3 = obj->startsWith(prefix);
*/
亿点收获:
思路+解法:
哈希表 + 链表:O(1)
struct Node{
int key, val;
Node* pre;
Node* next;
Node(int k, int v): key(k), val(v), pre(nullptr), next(nullptr) {}
Node(): key(0), val(0), pre(nullptr), next(nullptr) {}
};
class LRUCache {
private:
unordered_map<int ,Node*> m;
int size, capacity;
Node* drummyHead;
Node* drummyTail;
public:
LRUCache(int capacity) {
size = 0;
this -> capacity = capacity;
drummyHead = new Node();
drummyTail = new Node();
drummyHead->pre = nullptr;
drummyHead->next = drummyTail;
drummyTail->pre = drummyHead;
drummyTail->next = nullptr;
}
int get(int key) {
//cout << "get:"<< key << endl;
if(m.find(key) != m.end()){
Node* node = m[key];
move_to_head(node);
return node->val;
}
return -1;
}
void put(int key, int value) {
//cout << "put:"<< key;
if(m.find(key) != m.end()){
Node* node = m[key];
move_to_head(node);
node->val = value;
}
else{
Node* node = new Node(key, value);
m[key] = node;
if(size == capacity){
delete_tail();
add_to_head(node);
}else{
add_to_head(node);
size++;
}
}
/*for(Node* b = drummyHead->next; b != drummyTail; b = b->next) cout << b->val << " ";
cout << m.size();
cout << endl;*/
}
void move_to_head(Node* node){
Node* prenode = node->pre;
Node* nextnode = node->next;
prenode->next = nextnode;
nextnode->pre = prenode;
Node* headnextnode = drummyHead->next;
drummyHead->next = node;
node->pre = drummyHead;
node->next = headnextnode;
headnextnode->pre = node;
}
void add_to_head(Node* node){
Node* headnextnode = drummyHead->next;
drummyHead->next = node;
node->pre = drummyHead;
node->next = headnextnode;
headnextnode->pre = node;
}
void delete_tail(){
Node* tailpreprenode = drummyTail->pre->pre;
Node* tailprenode = drummyTail->pre;
tailpreprenode->next = drummyTail;
drummyTail->pre = tailpreprenode;
m.erase(tailprenode->key);
delete tailprenode;
}
};
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache* obj = new LRUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/
思路+解法:
贪心 O(n)
class Solution {
public:
int maxProfit(vector<int>& prices) {
int buy = prices[0];
int ans = 0;
int n = prices.size();
for(int i = 1; i < n; ++i){
if(prices[i] > buy) ans = max(ans, prices[i] - buy);
buy = min(buy, prices[i]);
}
return ans;
}
};
动态规划 O(n)
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
//持有股票、不持有股票时手中的现金量
vector<vector<int>> dp(n, vector<int>(2));
dp[0][0] = -prices[0];
dp[0][1] = 0;
for(int i = 1; i < n; i++){
dp[i][0] = max(dp[i - 1][0], -prices[i]);
dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);
}
return dp[n - 1][1];
}
};
思路+解法:
动态规划 O(n)
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
vector<vector<int>> dp(n, vector(2, 0));
dp[0][0] = -prices[0];
dp[0][1] = 0;
for(int i = 1; i < n; i++){
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);
}
return dp[n - 1][1];
}
};
贪心 O(n)
思路+解法:
动态规划 O(n)
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
vector<vector<int>> dp(n, vector<int>(5, 0));
dp[0][0] = 0;
dp[0][1] = -prices[0];
dp[0][2] = 0;
dp[0][3] = -prices[0];
dp[0][4] = 0;
for(int i = 1; i < n; i++){
dp[i][0] = dp[i - 1][0];
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
}
return dp[n - 1][4];
}
};
思路+解法:
动态规划 O(n * k)
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
if (prices.size() == 0) return 0;
int n = prices.size();
vector<vector<int>> dp(n, vector<int>(2 * k + 1, 0));
dp[0][0] = 0;
for(int i = 1; i < 2 * k + 1; i += 2){
dp[0][i] = -prices[0];
dp[0][i + 1] = 0;
}
for(int i = 1; i < n; i++){
dp[i][0] = dp[i - 1][0];
for(int j = 1; j < 2 * k + 1; j += 2){
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] - prices[i]);
dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] + prices[i]);
}
}
return dp[n - 1][2 * k];
}
};
思路+解法:
动态规划 O(n)
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int n = prices.size();
vector<vector<int>> dp(n, vector<int>(2, 0));
dp[0][0] = -prices[0] - fee;
dp[0][1] = 0;
for(int i = 1; i < n; i++){
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i] - fee);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
}
return dp[n - 1][1];
}
};