Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7222ec6

Browse files
committed
新增部分DP算法
1 parent 3fe6a59 commit 7222ec6

File tree

13 files changed

+593
-223
lines changed

13 files changed

+593
-223
lines changed

‎README.md‎

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
| 1| [两数之和](https://leetcode-cn.com/problems/two-sum/) | [twoSum](./array/leetcode/easy/twoSum.h) | <font color=green>easy</font> ||
66
| 2| [两数相加](https://leetcode-cn.com/problems/add-two-numbers/) | [addTwoNumbers](./linkedList/leetcode/medium/addTwoNumbers.h) | <font color=orange> medium </font> ||
77
| 3| [无重复字符的最长子串](https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/) | [lengthOfLongestSubstring](./string/leetcode/medium/lengthOfLongestSubstring.h) | <font color=orange> medium </font> ||
8-
| 5| [最长回文子串](https://leetcode-cn.com/problems/longest-palindromic-substring/) | [longestPalindrome](./string/leetcode/medium/longestPalindrome.h) | <font color=orange> medium </font>[需要回看其他解法]||
8+
| 5| [最长回文子串](https://leetcode-cn.com/problems/longest-palindromic-substring/) | [longestPalindrome](./string/leetcode/medium/longestPalindrome.h) | <font color=orange> medium </font>||
99
| 6| [Z字形变换](https://leetcode-cn.com/problems/zigzag-conversion/) | [zigzag_conversion](./string/leetcode/medium/zigzag_conversion.h) | <font color=orange> medium </font>||
1010
| 7| [整数反转](https://leetcode-cn.com/problems/reverse-integer/) | [reverse_integer](./other/leetcode/easy/reverse_integer.h) | <font color=green>easy</font> ||
1111
| 8| [字符串转换整数 (atoi)](https://leetcode-cn.com/problems/string-to-integer-atoi/) | [string_to_integer_atoi](./string/leetcode/medium/string_to_integer_atoi.h) | <font color=orange> medium </font> ||
@@ -106,10 +106,10 @@
106106
回溯算法是"万金油"。基本上贪心和dp能解决的问题,回溯都能解决。回溯相当于穷举搜索,列举出所有的情况,然后对比得到最优解。不过回溯的复杂度一般都是指数级的,只能用来解决小规模数据的问题。-->
107107

108108

109-
## [贪心](./greed.md)🚶🚶🚶🚶❌
110-
## [回溯算法](./backtracking.md)
111-
## [分治算法](./divideandconquer.md)
112-
## [动态规划](./dp.md)
109+
## [贪心](./greed.md)
110+
## [回溯算法](./backtracking.md)
111+
## [分治算法](./divideandconquer.md)🚶🚶🚶🚶
112+
## [动态规划](./dp.md)
113113

114114

115115
## [字符串匹配](./stringmatch.md)
@@ -127,27 +127,6 @@
127127

128128
## [数组](./array.md)
129129

130-
数组有两个关键词:
131-
132-
* 线性表结构, 就是说元素之间只有前后关系
133-
* 连续的内存空间,存储的是具有相同类型的数据
134-
135-
第二个特征决定了数组<font size=5 color=red>"随机访问"</font>的能力,因为我们完全可以通过地址计算出下标对应的位置。比如:
136-
137-
<font size=5>a[i]_add = base_add + i * type_size</font>
138-
139-
有利就有弊,也正是由于内存连续,所以数组的插入和删除是非常低效的,因为为了保持内存的连续,就意味着每次插入/删除都要伴随着<font size=5 color=red>大量的移动操作</font>,平均负责度为o(n).
140-
141-
142-
<font size=5 color=red>容器类</font>在数组的基础上,封装了插入删除等操作,同时支持了动态扩容. 需要注意的是,如果实现知道数组的大小,最好提前指定容器大小,这样可以省掉多次的内存申请和数据搬移。
143-
144-
大多情况下的<font size=5 color=red>解题思路</font>:
145-
146-
* 双指针
147-
* DP
148-
* 二分查找
149-
150-
151130
## [链表](./linkedList.md)
152131
## [栈&队列](./stack_queue.md)
153132

‎alg-cpp.xcodeproj/project.pbxproj‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@
193193
09421FFA23142AEB00A7BA67 /* searchRange.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = searchRange.h; sourceTree = "<group>"; };
194194
09421FFD231583FC00A7BA67 /* isValidSudoku.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = isValidSudoku.h; sourceTree = "<group>"; };
195195
0942542C232942D3006B83E9 /* gas_station.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = gas_station.h; sourceTree = "<group>"; };
196+
094524B7234790CD00CCBFB9 /* coinChange.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = coinChange.h; sourceTree = "<group>"; };
197+
094524BA234A32D000CCBFB9 /* levenshtein_distance.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = levenshtein_distance.h; sourceTree = "<group>"; };
196198
0946B01522F68BA50043469D /* FirstNotRepeatingChar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FirstNotRepeatingChar.h; sourceTree = "<group>"; };
197199
0946B01822F695CE0043469D /* ReverseSentence.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReverseSentence.h; sourceTree = "<group>"; };
198200
0946B01B22F6A5BF0043469D /* StrToInt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StrToInt.h; sourceTree = "<group>"; };
@@ -224,6 +226,7 @@
224226
0965B3CE23045B1C009A153E /* addBinary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = addBinary.h; sourceTree = "<group>"; };
225227
0965B3D223046663009A153E /* climbStairs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = climbStairs.h; sourceTree = "<group>"; };
226228
0965B3D523046775009A153E /* romanToInt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = romanToInt.h; sourceTree = "<group>"; };
229+
09665E9C234CD7ED003D0FAE /* pascals_triangle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pascals_triangle.h; sourceTree = "<group>"; };
227230
0969A71B22E607E800CA9347 /* string */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = string; sourceTree = BUILT_PRODUCTS_DIR; };
228231
0969A71D22E607E800CA9347 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
229232
0969A72222E6081500CA9347 /* matching.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = matching.h; sourceTree = "<group>"; };
@@ -290,6 +293,7 @@
290293
09FC39212305A42B00F0A2AE /* addTwoNumbers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = addTwoNumbers.h; sourceTree = "<group>"; };
291294
09FC39252305A9A500F0A2AE /* lengthOfLongestSubstring.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = lengthOfLongestSubstring.h; sourceTree = "<group>"; };
292295
09FC39282305B35900F0A2AE /* longestPalindrome.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = longestPalindrome.h; sourceTree = "<group>"; };
296+
3A04E7432341F1B7006770AF /* double11advance.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = double11advance.h; sourceTree = "<group>"; };
293297
3A091A2C22EFE34800EFA79C /* inorderTraversal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = inorderTraversal.h; sourceTree = "<group>"; };
294298
3A091A2F22EFE62E00EFA79C /* isValidBST.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = isValidBST.h; sourceTree = "<group>"; };
295299
3A091A3222F0450400EFA79C /* invertTree.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = invertTree.h; sourceTree = "<group>"; };
@@ -708,6 +712,10 @@
708712
3AD40CDC22EAF129002D60A6 /* leetcode */,
709713
0998EB8C22E75FB9005A01B5 /* main.cpp */,
710714
0998EB9122E75FEC005A01B5 /* knapsack.h */,
715+
094524B7234790CD00CCBFB9 /* coinChange.h */,
716+
3A04E7432341F1B7006770AF /* double11advance.h */,
717+
094524BA234A32D000CCBFB9 /* levenshtein_distance.h */,
718+
09665E9C234CD7ED003D0FAE /* pascals_triangle.h */,
711719
);
712720
path = dp;
713721
sourceTree = "<group>";
1.67 KB
Binary file not shown.
7.91 KB
Binary file not shown.

‎alg-cpp.xcodeproj/xcuserdata/junl.xcuserdatad/xcschemes/xcschememanagement.plist‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,22 @@
2222
<key>base.xcscheme_^#shared#^_</key>
2323
<dict>
2424
<key>orderHint</key>
25-
<integer>7</integer>
25+
<integer>5</integer>
2626
</dict>
2727
<key>bsearch.xcscheme_^#shared#^_</key>
2828
<dict>
2929
<key>orderHint</key>
30-
<integer>8</integer>
30+
<integer>9</integer>
3131
</dict>
3232
<key>divideandconquer.xcscheme_^#shared#^_</key>
3333
<dict>
3434
<key>orderHint</key>
35-
<integer>13</integer>
35+
<integer>14</integer>
3636
</dict>
3737
<key>dp.xcscheme_^#shared#^_</key>
3838
<dict>
3939
<key>orderHint</key>
40-
<integer>10</integer>
40+
<integer>12</integer>
4141
</dict>
4242
<key>greed.xcscheme_^#shared#^_</key>
4343
<dict>
@@ -47,12 +47,12 @@
4747
<key>hasTable.xcscheme_^#shared#^_</key>
4848
<dict>
4949
<key>orderHint</key>
50-
<integer>11</integer>
50+
<integer>10</integer>
5151
</dict>
5252
<key>linkedList.xcscheme_^#shared#^_</key>
5353
<dict>
5454
<key>orderHint</key>
55-
<integer>9</integer>
55+
<integer>6</integer>
5656
</dict>
5757
<key>other.xcscheme_^#shared#^_</key>
5858
<dict>
@@ -62,17 +62,17 @@
6262
<key>recursion.xcscheme_^#shared#^_</key>
6363
<dict>
6464
<key>orderHint</key>
65-
<integer>14</integer>
65+
<integer>13</integer>
6666
</dict>
6767
<key>sort.xcscheme_^#shared#^_</key>
6868
<dict>
6969
<key>orderHint</key>
70-
<integer>5</integer>
70+
<integer>8</integer>
7171
</dict>
7272
<key>stack+queue.xcscheme_^#shared#^_</key>
7373
<dict>
7474
<key>orderHint</key>
75-
<integer>6</integer>
75+
<integer>7</integer>
7676
</dict>
7777
<key>string.xcscheme_^#shared#^_</key>
7878
<dict>
@@ -82,7 +82,7 @@
8282
<key>tree.xcscheme_^#shared#^_</key>
8383
<dict>
8484
<key>orderHint</key>
85-
<integer>12</integer>
85+
<integer>11</integer>
8686
</dict>
8787
</dict>
8888
<key>SuppressBuildableAutocreation</key>

‎divideandconquer.md‎

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
1-
## 分治算法
1+
# 分治算法
22

3-
### <font color=red>经典题型</font>
3+
分治算法的核心思想就是分而治之。将原问题划分成n个规模较小,并且结构与原问题相似的子问题,然后递归的求解这些子问题,再将子问题的解合并成结果,就得到了原问题的解。
4+
5+
6+
分治算法能解决的问题,一般要满足下面几个条件:
7+
8+
1. 原问题和分解的小问题具有相同的求解模式.
9+
2. 分解的子问题可以独立求解,子问题之间没有任何关联,这是分治和动态规划最明显的区别
10+
3. 具有分解的终止条件,也就是说当问题足够小时,可以直接求解.
11+
4. 可以将子问题的求解合并成原问题,而这个合并操作的复杂度不能太高,否则就起不到减少算法总体的复杂度恶效果了。
12+
13+
14+
15+
16+
## <font color=red>经典题型</font>
417

518

619
| &emsp;题型&emsp; | 答案链接 | 完成度 |
720
| :--: | :----------------------------------------------------------- | :--------: |
8-
| 求一组数据里面的逆序对 | [reversedOrderPairs](./divideConquer/reversedOrderPairs.h)||
9-
| 二维平面上有n个点,如何快速求出最近的两个点之间的距离 | [closestPair](./divideConquer/closestPair.h)||
21+
| 求一组数据里面的逆序对 | [reversedOrderPairs](./divideandconquer/reversedOrderPairs.h)||
22+
| 二维平面上有n个点,如何快速求出最近的两个点之间的距离 | [closestPair](./divideandconquer/closestPair.h)||
1023

11-
### leetcode
24+
## leetcode
1225
| &emsp;题号&emsp; | 题目链接&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;| 答案链接&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;| &emsp;难度&emsp; | &emsp;完成度&emsp; |
1326
| :--: | :--: | :----------------------------------------------------------- | :----------------------------------------------------------- | :------: |
1427
| 17 | [电话号码的字母组合](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/)| --| ✨✨ ||

‎dp.md‎

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
1-
## 动态规划
1+
# 动态规划
2+
3+
4+
5+
我们把问题的求解分成N个阶段,每个阶段对应一次选择,每次选择之后,会产生不同的状态,我们记录每个阶段的这些状态。然后通过当前的状态集合推导出下一阶段的状态集合,动态的向前推进。
6+
7+
就拿0-1背包问题来说,回溯和动态规划都能解决这个问题。只不过回溯算法解决起来的效率是很低的,时间复杂度是指数级别的,而动态规划在执行效率方面就提高很多,尽管执行效率提高了,但是动态规划的空间复杂度也提高了,所以很多时候我们会说动态规划是一种空间换时间的算法。
8+
9+
10+
11+
## 什么样的问题适合使用动态规划来解决?
12+
13+
14+
动态规划适合用于<font size=5 color=red>多阶段决策最优解模型</font>, 就是说动态规划一般是用来解决最优解问题,而解决问题的过程需要经历多个阶段,每个阶段决策之后会对应一组状态,然后我们寻找一组决策序列,经过这组决策序列,最终求出问题的最优解。
15+
16+
217

318

419
### <font color=red>经典题型</font>
520

621
| &emsp;题型&emsp; | 答案链接 | 完成度 |
722
| :--: | :----------------------------------------------------------- | :--------: |
823
| 0-1背包问题及变种 | [knapsack](./dp/knapsack.h)||
9-
| 双11打折优惠问题 | [double11advance](./dp/knapsack.h)||
10-
| 硬币找零问题 | [coinChange2](./dp/knapsack.h)||
24+
| 双11打折优惠问题 | [double11advance](./dp/double11advance.h)||
25+
| 硬币找零问题 | [coinChange2](./dp/coinChange.h)||
26+
| 杨辉三角变种 | [pascals_triangle](./dp/pascals_triangle.h)||
1127
| 莱文斯坦最短编辑距离 | -- ||
1228
| 两个字符串的最长公共子序列 | -- ||
1329
| 数据序列的最长递增子序列 | -- ||

‎dp/coinChange.h‎

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//
2+
// coinChange.h
3+
// dp
4+
//
5+
// Created by junl on 2019年10月4日.
6+
// Copyright © 2019 junl. All rights reserved.
7+
//
8+
9+
#ifndef coinChange_hpp
10+
#define coinChange_hpp
11+
12+
#include <stdio.h>
13+
/*
14+
硬币找零问题。比如我们现在有硬币1元,3元,5元,我们需要支付w元,那么最少需要多少个硬币.
15+
思路:
16+
1. 贪心法,每次首先尝试最大面值的币种
17+
*/
18+
class coinChange {
19+
public:
20+
//贪心法,首先尝试最大面值的币种
21+
void solve(const int coins[], int n, int money, int currentCoinCount){
22+
if (money == 0 || currentCoinCount == n) {
23+
result = std::min(result, currentCoinCount);
24+
return;
25+
}
26+
for (int i=n-1; i>=0; i--) {
27+
if (money >= coins[i]) {
28+
solve(coins, n, money - coins[i], currentCoinCount+1);
29+
}
30+
}
31+
32+
}
33+
int solve(const int coins[], int n, int money){
34+
solve(coins, n, money, 0);
35+
return result;
36+
}
37+
private:
38+
int result = INT_MAX;
39+
};
40+
41+
class coinChange_dp {
42+
public:
43+
int solve(const int coins[], int n, int money){
44+
//这个找零问题,每次决策后有几个状态变量,第一个是当前的money,第二个是当前使用的硬币数量.所以状态里面至少要包含这两个变量
45+
46+
int max_coin_count = money; //n个1元
47+
bool st[max_coin_count][money+1];
48+
memset(st, false, sizeof(st));
49+
50+
//选择第一个硬币的初始状态
51+
for (int i=0; i<n; i++) {
52+
if (coins[i] <= money) {
53+
st[0][coins[i]] = true;
54+
}
55+
}
56+
57+
for (int index=1; index <= max_coin_count; index++) { //使用第index个硬币的状态
58+
for (int last_money = 1; last_money <= money; last_money++) {//计算出使用index个硬币所有可达的状态
59+
if (st[index-1][last_money]) { //如果last_money是可达状态,即可以通过硬币筹出来,那么计算下一个阶段的状态
60+
for (int k=n-1; k>=0; k--) {
61+
if (last_money + coins[k] <= money) {
62+
st[index][last_money + coins[k]] = true;
63+
}
64+
}
65+
}
66+
67+
if (st[index][money]) {
68+
return index+1;
69+
}
70+
}
71+
}
72+
return -1;
73+
74+
};
75+
};
76+
77+
78+
79+
80+
81+
void test_coinChange(){
82+
std::cout << "------------硬币找零问题----------\n" << std::endl;
83+
class coinChange so;
84+
class coinChange_dp so_dp;
85+
int coins[] = {1,3,5};
86+
std::cout << so.solve(coins, 3, 9) << std::endl;
87+
std::cout << so_dp.solve(coins, 3, 9) << std::endl;
88+
}
89+
90+
91+
#endif /* coinChange_hpp */

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /