最近稍閒,就刷leetcode玩,說是爲了準備找工做,其實就是好玩,由於好水啊哈哈哈哈。node
混了個國獎,感受我乾的像樣一點的事情都跟我無關,因此仍是,努力讓本身變成一個更好的人吧。c++
從今天起就記錄一下我沒有1A或者有意思的題目吧。算法
2015.10.16ide
Contains Duplicate IIIspa
Given an array of integers, find out whether there are two distinct indices i and j in the array such that the difference between nums[i] and nums[j] is at most t and the difference between i and j is at most k.c++11
class Solution { public: bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) { multiset<int> m; for (int i = 0;i<nums.size();i++) { if (i>=k+1) m.erase(nums[i-k-1]); auto lb = m.lower_bound(nums[i]-t); if (lb != m.end() && (*lb)-t<=nums[i]) return true; m.insert(nums[i]); } return false; } };
沒有1A的緣由:nums[i]+t會超int,好吧,相似還有一個二分題中間,m=(l+r)/2也會超過int。順便記一下,INT_MAX, INT_MIN, 記得想一想就好。code
這道題目的想法仍是挺直觀的,只是發現用stl寫,真的好省事。orm
Max Points on a Lineblog
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.遞歸
class Solution { public: int maxPoints(vector<Point>& points) { int ret = 0; for (auto &i : points) { unordered_map<long double,int> m; int dup = 0; for (auto& j : points) { if (i.x == j.x && i.y == j.y) dup++; else { if (i.x == j.x) m[INFINITY]++; else m[((long double)i.y - j.y)/((long double)i.x - j.x)]++; } } int localMax = 0; for (auto &x : m) localMax = max(localMax,x.second); localMax += dup; ret = max(ret,localMax); } return ret; } };
也是感嘆一下 STL讓程序變的更加美觀
還有for循環,最近接觸了c++11的寫法
10.23
Best Time to Buy and Sell Stock IV
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most k transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
這道題目仍是有點意思的
比較容易想到動態規劃, f[k][n]表示k次交易在前n天的最大收益
f[k][n] = max{f[k-1][n],f[k][n-1],max{f[k-1][p] - a[p+1] + a[n]} }
直接這樣是O(k*n^2), 能夠後面那一項存下來,理解爲持多倉一手的最大收益。
貼個
class Solution { public: int maxProfit(int k, vector<int>& a) { int Len = a.size(); if (!Len || !k) return 0; // if (k >= Len/2) { int ret = 0; for (int i = 0;i<Len-1;i++) if (a[i] < a[i+1]) ret+= a[i+1] - a[i]; return ret; } // vector<vector<int>> f = vector<vector<int>>(2,vector<int>(Len,0)); for (int i = 1;i<=k;i++) { int maxLong = -a[0]; for (int j = 1;j<Len;j++) { int i1 = i & 1; f[i1][j] = max(f[1-i1][j],f[i1][j-1]); f[i1][j] = max(f[i1][j],maxLong + a[j]); maxLong = max(maxLong,f[1-i1][j-1] - a[j]); } } return f[k&1][Len-1]; } };
還有O(n)算法
最優的交易策略必定是在極小值點買入,在極大值點賣出的
預處理能夠獲得全部波谷波峯對$(v_i,p_i)$,注意能夠捨去第一個波峯和最後一個波谷
若是不限制交易的次數,那麼能夠獲得每一個$(v_i,p_i)$對的收益$\sum(p_i-v_i)$
限制了交易的次數,有些波動是吃不到的,最好能吃到最大的k個向上波動
爲了讓選取最大的k個波動的算法可行,必須消除兩對(v,p)間的相互影響
對於前後出現的兩對$(v_i,p_i)$, $(v_j,p_j)$, 若是$v_i >= v_j$ 那麼最優的策略不可能$v_i$買入之後到$v_j$尚未賣出, 由於在$v_j$買入不會比$v_i$買入等到$v_j$多花錢,因此這兩個對是不相互影響的
精髓:
若是$p_j>p_i$, 那麼若是多一次交易機會,能夠多吃到$(p_i - v_j)$這個利潤
能夠等價成$(v_j,p_i)$ ,$(v_i ,p_j)$兩個對,若是隻有一次機會, 就作進大的這一對, 若是多一次交易機會, 就把小的利潤也作進去.
具體實現用到了棧
貼:
class Solution { public: stack<pair<int,int>> st; int maxProfit(int k, vector<int>& a) { int v = 0; int p = 0; int Len = a.size(); vector<int> pro; while (v < Len) { while (v+1 < Len && a[v+1]<=a[v]) v++; p = v+1; if (p == Len) break; while (p+1 < Len && a[p+1]>=a[p]) p++; int av = a[v]; int ap = a[p]; v = p+1; while (!st.empty() && av <= st.top().first) { pro.push_back(st.top().second - st.top().first); st.pop(); } while (!st.empty() && ap > st.top().second) { pro.push_back(st.top().second - av); av = st.top().first; st.pop(); } st.push({av,ap}); } while (!st.empty()) { pro.push_back(st.top().second - st.top().first); st.pop(); } sort(pro.begin(),pro.end(),[](int a,int b){return a>b;}); int ret = 0; if (k>pro.size()) k = pro.size(); for (int i = 0;i<k;i++) ret+=pro[i]; return ret; } };
Linked List Cycle II
Given a linked list, return the node where the cycle begins. If there is no cycle, return null
.
Note: Do not modify the linked list.
Follow up:
Can you solve it without using extra space?
貼個代碼吧,記住就好,挺有意思的算法
class Solution { public: ListNode *detectCycle(ListNode *head) { if (!head) return NULL; auto p = head; auto q = head; int cnt = 0; for (;;) { cnt++; p = p->next; q = q->next; if (!q) return NULL; q = q->next; if (!q) return NULL; if (p == q) break; } p = head; while (p!=q) { p = p->next; q = q->next; } return p; } };
10.24
Word Break II
Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.
Return all such possible sentences.
For example, given
s = "catsanddog"
,
dict = ["cat", "cats", "and", "sand", "dog"]
.
A solution is ["cats and dog", "cat sand dog"]
.
class Solution { public: map<string,vector<string>> m; vector<string> combine(const string& s,vector<string> vs) { if (vs.size()==1 && vs[0] == ""){return vector<string>{s};} vector<string> ret; for (auto& x : vs) ret.push_back(s + " " + x); return ret; } vector<string> wordBreak(string s, unordered_set<string>& Dict) { vector<string> ret; if (s == "") { ret.push_back(s); return ret; } if (m.find(s)!=m.end()) return m[s]; for (int i = 1;i<=s.length();i++) if (Dict.count(s.substr(0,i))) { auto tmp =combine(s.substr(0,i),wordBreak(s.substr(i,s.length()-i),Dict)); ret.insert(ret.end(),tmp.begin(),tmp.end()); } m[s] = ret; return ret; } };
再次感嘆一下STL的強大,感受STL讓程序更加簡潔,易懂。這個程序不用STL的話,是很是冗長的。
Clone Graph
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.
OJ's undirected graph serialization:
Nodes are labeled uniquely.
We use # as a separator for each node, and , as a separator for node label and each neighbor of the node.
As an example, consider the serialized graph {0,1,2#1,2#2,2}.
The graph has a total of three nodes, and therefore contains three parts as separated by #.
First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
Second node is labeled as 1. Connect node 1 to node 2.
Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.
貼:
class Solution { public: unordered_map<UndirectedGraphNode*,UndirectedGraphNode*> m; UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { if (!node) return node; if (m.find(node) != m.end()) return m[node]; auto ret = new UndirectedGraphNode(node->label); m[node] = ret; for (auto& x : node->neighbors) ret->neighbors.push_back(cloneGraph(x)); return ret; } };
STL+遞歸,不談了。