forked from wisdompeak/LeetCode
-
Notifications
You must be signed in to change notification settings - Fork 1
[pull] master from wisdompeak:master #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
21c5983
Update 642.Design-Search-Autocomplete-System.cpp
wisdompeak 8f5c9fb
Update Readme.md
wisdompeak 57e78dd
Create 2311.Longest-Binary-Subsequence-Less-Than-or-Equal-to-K_v1.cpp
wisdompeak 64d401c
Create 2311.Longest-Binary-Subsequence-Less-Than-or-Equal-to-K_v2.cpp
wisdompeak 16bd37e
Update 2311.Longest-Binary-Subsequence-Less-Than-or-Equal-to-K_v1.cpp
wisdompeak 99fca9d
Create Readme.md
wisdompeak 655136c
Update Readme.md
wisdompeak 36cd4a4
Create 2312.Selling-Pieces-of-Wood.cpp
wisdompeak 99bb6dd
Update Readme.md
wisdompeak 0cb6957
Create Readme.md
wisdompeak 54e342b
Update Readme.md
wisdompeak 94b6826
Create 2222.Number-of-Ways-to-Select-Buildings.cpp
wisdompeak fbf5e9a
Update Readme.md
wisdompeak 99304f3
Create Readme.md
wisdompeak 7d629b3
Update 2222.Number-of-Ways-to-Select-Buildings.cpp
wisdompeak f3ef226
Update Readme.md
wisdompeak File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
110 changes: 64 additions & 46 deletions
Design/642.Design-Search-Autocomplete-System/642.Design-Search-Autocomplete-System.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1,88 @@ | ||
class AutocompleteSystem { | ||
unordered_map<string,int>Map; | ||
string data; | ||
|
||
struct cmp | ||
class TrieNode | ||
{ | ||
public: | ||
TrieNode* next[128]; | ||
set<pair<int,string>>top; | ||
TrieNode() | ||
{ | ||
bool operator()(pair<string,int>a, pair<string,int>b) | ||
{ | ||
if (a.second==b.second) | ||
return a.first<b.first; | ||
else | ||
return a.second>b.second; | ||
} | ||
}; | ||
for (int i=0; i<128; i++) | ||
next[i] = NULL; | ||
} | ||
}; | ||
|
||
class AutocompleteSystem { | ||
TrieNode* root; | ||
string inputStr; | ||
TrieNode* cur; | ||
int flag = 1; | ||
public: | ||
AutocompleteSystem(vector<string> sentences, vector<int> times) | ||
AutocompleteSystem(vector<string>& sentences, vector<int>& times) | ||
{ | ||
root = new TrieNode(); | ||
cur = root; | ||
for (int i=0; i<sentences.size(); i++) | ||
Map[sentences[i]]=times[i]; | ||
data.clear(); | ||
add(root, sentences[i], 0, -times[i]); | ||
} | ||
|
||
void add(TrieNode* node, const string sentence, int i, int freq) | ||
{ | ||
if (i==sentence.size()) return; | ||
|
||
int k = sentence[i]; | ||
if (node->next[k] == NULL) | ||
node->next[k] = new TrieNode(); | ||
node = node->next[k]; | ||
|
||
int f = 0; | ||
for (auto iter = node->top.begin(); iter!=node->top.end(); iter=next(iter)) | ||
{ | ||
if (iter->second == sentence) | ||
f = iter->first; | ||
} | ||
if (f!=0) node->top.erase({f, sentence}); | ||
node->top.insert(make_pair(f+freq, sentence)); | ||
|
||
add(node, sentence, i+1, freq); | ||
} | ||
|
||
vector<string> input(char c) | ||
{ | ||
inputStr.push_back(c); | ||
|
||
if (c=='#') | ||
{ | ||
Map[data]++; | ||
data.clear(); | ||
inputStr.pop_back(); | ||
add(root, inputStr, 0, -1); | ||
inputStr = ""; | ||
cur = root; | ||
flag = 1; | ||
return {}; | ||
} | ||
|
||
data.push_back(c); | ||
priority_queue<pair<string,int>,vector<pair<string,int>>,cmp>pq; | ||
|
||
for (auto x:Map) | ||
else if (flag==0) | ||
{ | ||
string a=x.first; | ||
if (match(data,a)) | ||
{ | ||
pq.push({a,Map[a]}); | ||
if (pq.size()>3) pq.pop(); | ||
} | ||
return {}; | ||
} | ||
|
||
vector<string>results; | ||
while (!pq.empty()) | ||
else if (cur->next[c]==NULL) | ||
{ | ||
results.push_back(pq.top().first); | ||
pq.pop(); | ||
flag = 0; | ||
return {}; | ||
} | ||
reverse(results.begin(),results.end()); | ||
return results; | ||
} | ||
|
||
bool match(string a, string b) | ||
{ | ||
for (int i=0; i<a.size(); i++) | ||
|
||
cur = cur->next[c]; | ||
vector<string>rets; | ||
for (auto iter = cur->top.begin(); iter!=cur->top.end(); iter=next(iter)) | ||
{ | ||
if (i>=b.size() || a[i]!=b[i]) | ||
return false; | ||
rets.push_back(iter->second); | ||
if (rets.size()==3) break; | ||
} | ||
return true; | ||
return rets; | ||
|
||
} | ||
|
||
}; | ||
|
||
/** | ||
* Your AutocompleteSystem object will be instantiated and called as such: | ||
* AutocompleteSystem obj = new AutocompleteSystem(sentences, times); | ||
* vector<string> param_1 = obj.input(c); | ||
* AutocompleteSystem* obj = new AutocompleteSystem(sentences, times); | ||
* vector<string> param_1 = obj->input(c); | ||
*/ |
30 changes: 5 additions & 25 deletions
Design/642.Design-Search-Autocomplete-System/Readme.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,10 @@ | ||
### 642.Design-Search-Autocomplete-System | ||
|
||
如果不用trie来做的话,可以比较简单地用priority_queue来实现对所有候选语句的排序,选择最终未被弹出的三个字符串。 | ||
我们将所有的句子都构建入一棵字典树。对于每个节点(字母),我们都维护一个```句子-频次```的统计。也就是说,注入句子S时,我们将沿途经过的节点都标记上```freq[S]+=1```. | ||
|
||
核心代码非常简单: | ||
``` | ||
struct cmp | ||
{ | ||
bool operator()(pair<string,int>a, pair<string,int>b) | ||
{ | ||
if (a.second==b.second) | ||
return a.first<b.first; | ||
else | ||
return a.second>b.second; | ||
} | ||
}; | ||
priority_queue<pair<string,int>,vector<pair<string,int>>,cmp>pq; | ||
for (auto x:Map) | ||
{ | ||
string a=x.first; | ||
if (match(data,a)) | ||
{ | ||
pq.push({a,Map[a]}); | ||
if (pq.size()>3) pq.pop(); | ||
} | ||
} | ||
``` | ||
当依次读入input时,我们维护从root往下走的指针,移动至该单词对应的节点,读取它的freq取出前三名即可。freq需要使用一个自动排序的数据结构。 | ||
|
||
记得当input遇到#时,要将之前input的完整句子,从root开始再次构建入这棵字典树。 | ||
|
||
[Leetcode Link](https://leetcode.com/problems/design-search-autocomplete-system) | ||
|
||
[Leetcode Link](https://leetcode.com/problems/design-search-autocomplete-system) |
25 changes: 25 additions & 0 deletions
...mming/2222.Number-of-Ways-to-Select-Buildings/2222.Number-of-Ways-to-Select-Buildings.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using LL = long long; | ||
class Solution { | ||
LL dp[100005][4][2]; | ||
public: | ||
long long numberOfWays(string s) | ||
{ | ||
int n = s.size(); | ||
s = "#"+s; | ||
|
||
dp[0][0][0] = 1; | ||
dp[0][0][1] = 1; | ||
|
||
for (int i=1; i<=n; i++) | ||
for (int j=0; j<=3; j++) | ||
for (int k=0; k<2; k++) | ||
{ | ||
dp[i][j][k] = dp[i-1][j][k]; | ||
|
||
if (j>=1 && k==(s[i]-'0')) | ||
dp[i][j][k] += dp[i-1][j-1][1-k]; | ||
} | ||
|
||
return dp[n][3][0] + dp[n][3][1]; | ||
} | ||
}; |
9 changes: 9 additions & 0 deletions
Dynamic_Programming/2222.Number-of-Ways-to-Select-Buildings/Readme.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
### 2222.Number-of-Ways-to-Select-Buildings | ||
|
||
我们在考虑第i个建筑是否被选中时,需要考虑的因素有:我们已经选中了多少?上一个选中的和当前这个是否是同一个类型? | ||
|
||
想清楚这些,我们就可以设计状态:dp[i][j][k]表示考虑完第i幢建筑时,如果已经选中了j个,并且最近一个被选中的建筑类别是k时,总共有多少种方案。 | ||
|
||
状态转移时需要分两种情况:如果我们不选第i个建筑,那么自然dp[i][j][k] = dp[i-1][j][k]。如果我们选中第i个建筑,那么需要保证第i个建筑与类别k是匹配的,于是这就取决于之前解决过的一个问题:在前i-1个建筑里,选择j-1个,并且最近一个选中的建筑类别是1-k,这样的方案有多少。依据dp[i-1][j][1-k],再选中第i个建筑,就是dp[i][j][k]。 | ||
|
||
最终答案是dp[n][3][0]+dp[n][3][1]. |
22 changes: 22 additions & 0 deletions
Dynamic_Programming/2312.Selling-Pieces-of-Wood/2312.Selling-Pieces-of-Wood.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using LL = long long; | ||
class Solution { | ||
LL dp[201][201]; | ||
public: | ||
long long sellingWood(int m, int n, vector<vector<int>>& prices) | ||
{ | ||
for (auto x: prices) | ||
dp[x[0]][x[1]] = x[2]; | ||
|
||
for (int i=1; i<=m; i++) | ||
for (int j=1; j<=n; j++) | ||
{ | ||
for (int k=1; k<i; k++) | ||
dp[i][j] = max(dp[i][j], dp[k][j]+dp[i-k][j]); | ||
|
||
for (int k=1; k<j; k++) | ||
dp[i][j] = max(dp[i][j], dp[i][k]+dp[i][j-k]); | ||
} | ||
|
||
return dp[m][n]; | ||
} | ||
}; |
7 changes: 7 additions & 0 deletions
Dynamic_Programming/2312.Selling-Pieces-of-Wood/Readme.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
### 2312.Selling-Pieces-of-Wood | ||
|
||
令dp[i][j]表示高度为i、宽度为j的矩形所能得到的最大收益。因为任何一刀必须贯穿整块木板,并且两块木板可以继续各自独立地做进一步操作。显然这就是状态的转移。 | ||
|
||
假设这一刀是竖切,那么假设左半部分的宽度是k,那么就分成了大小为[i,k]和[i,j-k]的两部分。类似的,如果这一刀是横切,假设上半部分的高度是k,那么就分成了大小为[k,j]和[i-k,j]的两部分。所以我们只要从小到大遍历高和宽,就可以求出所有的dp[i][j]. | ||
|
||
边界条件是某些特定的高和宽恰好对应了prices里面的形状,那么他们的dp值除了可以通过上述分割的转移方程进行推导,也可以从prices里面得到。两者取大即可。 |
64 changes: 64 additions & 0 deletions
...ce-Less-Than-or-Equal-to-K/2311.Longest-Binary-Subsequence-Less-Than-or-Equal-to-K_v1.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
class Solution { | ||
public: | ||
int longestSubsequence(string s, int k) | ||
{ | ||
string t; | ||
while (k>0) | ||
{ | ||
if (k%2==0) | ||
t.push_back('0'); | ||
else | ||
t.push_back('1'); | ||
k/=2; | ||
} | ||
reverse(t.begin(), t.end()); | ||
|
||
int m = s.size(); | ||
int n = t.size(); | ||
|
||
if (m<n) return m; | ||
|
||
int ret = n-1; | ||
ret = max(ret, countZeros(s, m-n+1) + n-1); | ||
|
||
for (int i=m-1; i>=0; i--) | ||
{ | ||
if (check(s,i,t, 0)) | ||
{ | ||
ret = max(ret, countZeros(s, i) + n); | ||
break; | ||
} | ||
} | ||
|
||
return ret ; | ||
} | ||
|
||
int countZeros(string&s, int k) | ||
{ | ||
int count = 0; | ||
for (int i=0; i<k; i++) | ||
count+= s[i]=='0'; | ||
return count; | ||
} | ||
|
||
bool check(string& s, int i, string& t, int j) | ||
{ | ||
if (j==t.size()) return true; | ||
if (i==s.size()) return false; | ||
|
||
if (t[j]=='1') | ||
{ | ||
if (s[i]=='1') | ||
return check(s, i+1, t, j+1); | ||
else | ||
return (int)s.size() - i >= (int)t.size() - j; | ||
} | ||
else | ||
{ | ||
while (i<s.size() && s[i]=='1') | ||
i++; | ||
if (i==s.size()) return false; | ||
else return check(s, i+1, t, j+1); | ||
} | ||
} | ||
}; |
40 changes: 40 additions & 0 deletions
...ce-Less-Than-or-Equal-to-K/2311.Longest-Binary-Subsequence-Less-Than-or-Equal-to-K_v2.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
class Solution { | ||
public: | ||
int longestSubsequence(string s, int k) | ||
{ | ||
string t; | ||
while (k>0) | ||
{ | ||
if (k%2==0) | ||
t.push_back('0'); | ||
else | ||
t.push_back('1'); | ||
k/=2; | ||
} | ||
reverse(t.begin(), t.end()); | ||
|
||
int m = s.size(); | ||
int n = t.size(); | ||
|
||
if (m<n) return m; | ||
|
||
int ret = n-1; | ||
ret = max(ret, countZeros(s, m-n+1) + n-1); | ||
|
||
int i = m-n; | ||
if (s.substr(i) <= t) | ||
{ | ||
ret = max(ret, countZeros(s, i) + n); | ||
} | ||
|
||
return ret ; | ||
} | ||
|
||
int countZeros(string&s, int k) | ||
{ | ||
int count = 0; | ||
for (int i=0; i<k; i++) | ||
count+= s[i]=='0'; | ||
return count; | ||
} | ||
}; |
21 changes: 21 additions & 0 deletions
Greedy/2311.Longest-Binary-Subsequence-Less-Than-or-Equal-to-K/Readme.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
### 2311.Longest-Binary-Subsequence-Less-Than-or-Equal-to-K | ||
|
||
#### 解法1: | ||
我们将k同样也转化为二进制的字符串,标记为t。我们令s的长度是m,t的长度为n。注意,因为k是个整形,n的长度不会超过32. | ||
|
||
接下来考虑题目中说的"最长"是什么意思。通常情况下,长度小于n的二进制数一定小于k,长度大于n的二进制数一定会大于k,"最长"不就是n吗?本题的关键点在于leading zeros。所以,我们希望尽可能地在期望的subsequence前面堆积0,这就意味着我们希望将subsequence放在s里尽量靠后的位置。 | ||
|
||
所以我们本题的做法就是:在s里从后往前依次寻找一个起点位置i,判断是否存在一个从i开始的subsequence,使其小于等于t,有的话就再加上s[0:i-1]里的所有0的个数,就是期望的总长度。最后,我们在所有的i的选择里面挑一个答案最长的。 | ||
|
||
那么指定了起点i,如何判断是否存在一个subsequence小于等于t呢?用递归的方法贪心地扫描即可。如果t[j]是0,那么s[i]必须是0,于是移动i直至找到0,与之match,双指针再自增1。如果t[j]是1,那么如果s[i]是0,直接OK;如果s[j]是1,那么与之match,双指针都自增1. | ||
|
||
这种方法的时间复杂度是o(N^2) | ||
|
||
#### 解法2: | ||
在解法1的基础上,事实上我们不需要遍历所有起点位置,只需要考察一个位置i=m-n,也就是只需要考察最后一个长度为n的substring即可。这是为什么呢? | ||
|
||
先考虑basic plan:只看最后n-1长度的substring(必然小于t),再加上[0:m-n]之间的所有的0. 这显然是一个合法的解。 | ||
|
||
再考虑如果以i=m-n为起点、长度为n的substring,如果大于t的话(显然s的第i位必然是1),那么说明什么?说明缺0。我们必须将i往前移,目的是为了能够引入0,这样才可能将之后的subsequence的大小降下来。但是一旦真的能引入一个0进入subsequence,那么代价就是损失了一个leading zero。那么收益呢?收益就是将subsequence的匹配度从n-1提升到n而已,并没有优势。 | ||
|
||
所以本题非常简单,在考察完basic plan之后,只需要查看取最后长度n的substring是否为另一个plan即可。时间复杂度是o(N). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.