diff --git a/README.md b/README.md index 74e9c02..0b31c81 100644 --- a/README.md +++ b/README.md @@ -4,38 +4,6 @@ 2016年12月05日我们将开始第一次活动,大家一起来完成LeetCode第09题,并把解题过程记录下来,Pull到这个仓库。 -# 活动记录 - -## 20161215 百人刷题活动 - -这次刷Leetcode第13题 - -https://leetcode.com/problems/roman-to-integer/ - -大家可以往 leetcode/13 下pull代码 - -https://github.com/githubwoniu/learnprogram/tree/master/leetcode/13 - -## 20161205 百人刷题活动 - -学习群里的小伙伴们经常问我,为什么工作四年之后还要学习C++。 - -其实学习C++并不是我的最终目的,我是希望借助C++来系统的学习一下编程这门学科。 - -100天C++学习计划只是我的第一步。 - -截止到今天(20161204)已经是执行计划的第51天了,我的收获有: -1. 完成了前6章和第8章 -2. 分享了30多篇读书笔记到知乎和个人公众号 -3. 坚持6点半起床,早起已经不会有任何的不适 -4. 知乎有1490个关注,公众号有248个关注,c++学习群刚好100人,这些都是学习上的陪伴,可以经常一起探讨问题,分享学习方法,相互监督。 - -也是为了记念学习群满100人,和小伙伴们商量组织一个活动:百人刷leetcode大作战!! - -![](https://github.com/githubwoniu/learnprogram/blob/master/image/100leetcode.png) - -欢迎大家转发邀请卡,邀请好友一起学习,一起进步。 - ### 具体的GitHub操作如下 #### 1. Fork diff --git a/leetcode/01/note_BigBrother007.md b/leetcode/01/note_BigBrother007.md new file mode 100644 index 0000000..e49502d --- /dev/null +++ b/leetcode/01/note_BigBrother007.md @@ -0,0 +1,65 @@ +## 链接 + + +https://leetcode.com/problems/two-sum/ + + +## 题目 + + + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { +public: + vector twoSum(vector& nums, int target) { + int n = nums.size(); + int first = 0, second = 0; + for (int i = 0; i < n - 1; ++i) + { + for (int j = i + 1; j < n; ++j) + if (nums[i] + nums[j] == target) + { + first = i; + second = j; + break; + } + } + return vector {first, second}; + } +}; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/01/note_Josan.md b/leetcode/01/note_Josan.md new file mode 100644 index 0000000..01268bb --- /dev/null +++ b/leetcode/01/note_Josan.md @@ -0,0 +1,106 @@ +## 链接 + +https://leetcode.com/problems/two-sum/ + +## 题目 + +Given an array of integers, return **indices** of the two numbers such that they add up to a specific target. + +You may assume that each input would have **exactly** one solution. + +**Example:** + +``` +Given nums = [2, 7, 11, 15], target = 9, + +Because nums[0] + nums[1] = 2 + 7 = 9, +return [0, 1]. +``` + +**UPDATE (2016/2/13):** + The return format had been changed to **zero-based** indices. Please read the above updated description carefully. + + + +## 释义 + +输入一个整形数组nums,和目标数字c,要求在nums中找到满足a+b=c的两个数,并返回它们的下标。 + + + +## 补充描述 +看到好多写成Hash格式,主要目的就是快速查找。我这边来一个使用“Two-pointers Technology”技术的解法。 + +首先,大致的思想就是对数组进行排序,然后设置两个指针,一个指向头一个指向尾,前后逼近,就能判断是否找到对应的值。 + +但是这个题目返回原来的序号,所以进行排序的时候,原来的序号就发生改变,因此我引入了一个辅助数组vector,进行存放对应的序号。 + + +## 代码 + +```c++ +class Solution +{ + public: + vector twoSum(vector& nums, int target) + { + struct Node + { + int index; //原来的序号 + int num; //对应序号的数值 + }; + vector n_vec; + n_vec.reserve(nums.size()); + + //初始化n_vec + for(int i = 0; i != nums.size(); ++i) + { + n_vec.push_back(Node{ i, *(nums.begin() + i) }); + } + + //将n_vec按num进行排序 + sort(n_vec.begin(), n_vec.end(), [](Node lh, Node rh) { return lh.num < rh.num; }); + + + int i = 0, j = static_cast (nums.size() - 1); + while(i < j) + { + int temp = (n_vec.begin() + i)->num + (n_vec.begin() + j)->num; + if(temptarget) + { + --j; + } + else + { + break; + } + } + + + if(i < j) + { + int tem1 = (n_vec.begin() + i)->index, tem2 = (n_vec.begin() + j)->index; + if(tem1 < tem2) + { + return { tem1, tem2 }; + } + else + { + return { tem2, tem1 }; + } + + } + return vector(); + } +}; +``` +跑了两次,一次9ms;一次12ms    速度还可以 +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/01/note_Superllb.md b/leetcode/01/note_Superllb.md new file mode 100644 index 0000000..798287a --- /dev/null +++ b/leetcode/01/note_Superllb.md @@ -0,0 +1,28 @@ +#描述 +##解题思路 +###为了保证第一次查找有效,采用先插再查。之前提到数组里可能会有重复元素,bajdcc提示使用multimap,运行结果显示,两者结果相同。只要这个重复元素符合条件,返回的始终是第一次出现时对应的索引。 +###此外,例如```nums=[1,3,5,7,9],target=14```,如果不加判断,返回结果就会是```[3,3]```,而不是```[3,4]```。如果采用先查再插,这种情形不用考虑。 +#代码 +```cpp +class Solution { +public: + vector twoSum(vector& nums, int target) { + unordered_map unmap; + vector result; + for (int i = 0; i < nums.size(); ++i) { + //int x = target - nums[i]; + unmap.insert({nums[i],i}); + auto search = unmap.find(target - nums[i]); + if (search != unmap.end()) { + if (i != search->second){ + result.push_back(i); + result.push_back(search->second); + return result; + } + } + //unmap.insert({nums[i],i}); + } + return result; + } +}; +``` diff --git a/leetcode/01/note_Yac836.md b/leetcode/01/note_Yac836.md new file mode 100644 index 0000000..d8412ff --- /dev/null +++ b/leetcode/01/note_Yac836.md @@ -0,0 +1,46 @@ +## 链接 + + +https://leetcode.com/problems/two-sum/ + + +## 题目 + +Given an array of integers, return **indices** of the two numbers such that they add up to a specific target. + +You may assume that each input would have **exactly** one solution. + + + +## 释义 + +从一个数组中给出找出两个整数,和等于所给的目标值。 + + +## 补充描述 +下标从零开始 + +## 代码 +```c++ +vector twoSum(vector& nums, int target) { + decltype(nums.size()) len = nums.size(); + vector res; + for (decltype(nums.size()) i = 0; i < len; i++) { + for (decltype(nums.size()) j = i + 1; j < len; j++) { + if (nums[i] + nums[j] == target) { + res.push_back(i); + res.push_back(j); + } + } + } + return res; +} +``` + + + +## 更多 + +![d](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/01/note_ZgblKylin.md b/leetcode/01/note_ZgblKylin.md new file mode 100644 index 0000000..f4f1d03 --- /dev/null +++ b/leetcode/01/note_ZgblKylin.md @@ -0,0 +1,93 @@ +## 链接 + +https://leetcode.com/problems/two-sum/ + +## 题目 + +Given an array of integers, return **indices** of the two numbers such that they add up to a specific target. + +You may assume that each input would have **exactly** one solution. + +**Example:** + +``` +Given nums = [2, 7, 11, 15], target = 9, + +Because nums[0] + nums[1] = 2 + 7 = 9, +return [0, 1]. +``` + +**UPDATE (2016/2/13):** + The return format had been changed to **zero-based** indices. Please read the above updated description carefully. + + + +## 释义 + +输入一个整形数组nums,和目标数字c,要求在nums中找到满足a+b=c的两个数,并返回它们的下标。 + + + +## 补充描述 +第一反应是直观的写个双重循环,外层i从0到size,内层j从i+1到size,执行次数是n*(n+1)/2次,也就是O(n^2)……太可怕了,肯定过不了。 + +那么就得想办法优化了,优化效率的第一反应就是万恶的**打表法**…… + +假设数组中最小的数是1,最大的数是n,那么,我们是不是可以做一个长度为n的数组,初始为false,用输入数据作为下标,对应位置为true。 + +然后,我们只需要遍历一轮输入数据就行了,对于每个num,查询下target - num对应的布尔值是不是true,是的话就找到了。 + +这样的话,b的寻找不需要遍历,只需要一次索引查询,是常量级的,整体算法时间开销O(n)。 + + + +然而这么做的话,这个数组太大了,有办法优化么? + +答案是用hash,也就是unordered_map,这东东同样提供常量级(一般情况)的查询。 + +所以解决方案就出来了,做一个hash,key是num,value是index。然后遍历一下nums,对每个a,求它对应的b,查询下b在不在hash里,若存在就找到了。 + +然后为了提高效率,还可以把hash的初始化合并到查询中。 + +本来是这样的: + +1. 遍历nums,初始化hash +2. 遍历nums,查询hash,得到答案 + +现在可以写成这样: + +- 遍历nums,针对每一个num,查询hash + - 若存在则返回答案 + - 若不存在,则将num和其index插入hash。则下次遍历到它对应的b时,自然就能找到答案了。 + +这样的话,首先可以少一轮遍历,其次hash成员更少,查询效率更高,就酱。 + + + +## 代码 + +```c++ +class Solution { +public: + vector twoSum(vector& nums, int target) { + unordered_map num_index; + vector ret; + for(int index=0;index twoSum(vector& nums, int target) { + vector v; + map loc; + map c;//记录数字出现次数 + for(int i=nums.size()-1; i>=0; i--) + { + loc[nums[i]]=i; + c[nums[i]]++; + } + for(int i=0; i1) + { + v.push_back(i); + if(nums[i]*2!=target) + { + v.push_back(loc[target-nums[i]]); + } + else + { + int f=0; + for(int j=i+1; j> 1) ^ 0xbadbadcc; + key >>= 2; + } + value ^= k; + value ^= 0xccbadbad; + value = (value & 0xff); + value ^= (value & 0xff00) >> 8; + value ^= (value & 0xff0000) >> 16; + value ^= (value & 0xff000000) >> 24; + for (int i = 0; i < k % 0xf; i++) { + value = (k % 0xff) - value; + value = (value & 0xff); + } + return value; + } +``` + +问题来了:两个数的散列值一样怎么办?简单,用链表。 + +但是有人说了:链表太长了!那同样简单,一个结点保存5个值呗,用完再建。 + +最终就形成了下面的算法。 + +## 补充描述 + +提交:https://leetcode.com/submissions/detail/86803868/ + +用时:9ms,beat:96%(不用std就是快) + + +## 代码 + + + + +```c++ +#include +#include + +using namespace std; + +static const int INVALID_NUM = INT32_MIN; + +struct Pair { + int key, value; +}; + +class Hash { + static const int SEED = 0xbadbadcc; + static const int CACHE_SIZE = 0x100; + static const int CACHE_MIN = -CACHE_SIZE/2; + static const int CACHE_MAX = CACHE_SIZE/2; + int cache[CACHE_SIZE]; + static const int HASH_BITS = 8; + static const int NODE_SIZE = 1 << HASH_BITS; + static const int NODE_CHUNK_SIZE = 5; + class Node { + Pair data[NODE_CHUNK_SIZE]; + int index; + struct Node *next; + public: + Node() { + index = 0; + next = nullptr; + } + + ~Node() { + if (next) + delete next; + } + + void add(int key, int value) { + if (index >= NODE_CHUNK_SIZE) { + if (!next) { + next = new Node(); + } + next->add(key, value); + } else { + data[index].key = key; + data[index].value = value; + index++; + } + } + + int get(int key) const { + for (int i = 0; i < index; i++) { + if (data[i].key != INVALID_NUM && data[i].key == key) { + return data[i].value; + } + } + if (next) + return next->get(key); + return INVALID_NUM; + } + }; + Node data[NODE_SIZE]; + +public: + Hash() { + for (int i = 0; i < CACHE_SIZE; i++) { + cache[i] = INVALID_NUM; + } + } + + inline int hash(int key) const { + int value = 0xabcdabcd; + key += 0x12345678; + int k = key; + while (key) { + value += key & 0x3; + value = (value >> 1) ^ 0xbadbadcc; + key >>= 2; + } + value ^= k; + value ^= 0xccbadbad; + value = (value & 0xff); + value ^= (value & 0xff00) >> 8; + value ^= (value & 0xff0000) >> 16; + value ^= (value & 0xff000000) >> 24; + for (int i = 0; i < k % 0xf; i++) { + value = (k % 0xff) - value; + value = (value & 0xff); + } + return value; + } + + int get(int key) const { + if (key >= -CACHE_MIN && key < CACHE_MAX) { + return cache[key + CACHE_MIN]; + } + return data[hash(key)].get(key); + } + + void add(int key, int value) { + if (key >= -CACHE_MIN && key < CACHE_MAX) { + cache[key + CACHE_MIN] = value; + } else { + data[hash(key)].add(key, value); + } + } +}; + +class Solution { +public: + vector twoSum(vector &nums, int target) { + Hash hash; + int i, index = 0, value; + for (i = 0; i < nums.size(); i++) { + if ((index = hash.get(target - (value = nums[i]))) != INVALID_NUM) { + return vector{index, i}; + } + hash.add(value, i); + } + if (hash.get(target - nums[i]) != INVALID_NUM) { + return vector{index, i}; + } + return vector{-1, -1}; + } +}; +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/01/note_cormen.md b/leetcode/01/note_cormen.md new file mode 100644 index 0000000..4da9a2c --- /dev/null +++ b/leetcode/01/note_cormen.md @@ -0,0 +1,84 @@ +## 链接 + + +https://leetcode.com/problems/two-sum/ + + +## 题目 + + +Given an array of integers, return **indices** of the two numbers such that they add up to a specific target. + +You may assume that each input would have **exactly** one solution. + +**Example:** + +``` +Given nums = [2, 7, 11, 15], target = 9, + +Because nums[0] + nums[1] = 2 + 7 = 9, +return [0, 1]. +``` + +**UPDATE (2016/2/13):** + The return format had been changed to **zero-based** indices. Please read the above updated description carefully. + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { +public: + vector twoSum(vector& nums, int target) { + + vector result(2); + mapdic; + int len = nums.size(); + + for(int i = 0; i < len; i++) + { + if(dic.find(nums[i]) == dic.end()) + { + dic[target - nums[i]] = i; + } + else + { + result[0] = dic[nums[i]]; + result[1] = i; + } + } + return result; + } +}; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/01/note_leakey.md b/leetcode/01/note_leakey.md new file mode 100644 index 0000000..77693fb --- /dev/null +++ b/leetcode/01/note_leakey.md @@ -0,0 +1,58 @@ +## 链接 + + +https://leetcode.com/problems/two-sum/ + + +## 题目 + + + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { +public: + vector twoSum(vector& nums, int target) { + int i = 0, n = nums.size(); + unordered_map idx; + while (i < n && idx.find(target - nums[i]) == idx.end()) { // find the other number and not same with the current number + idx[nums[i++]] = i; + } + return {idx[target - nums[i]] - 1, i}; + } +}; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/03/note.md b/leetcode/03/note.md new file mode 100644 index 0000000..24aa51e --- /dev/null +++ b/leetcode/03/note.md @@ -0,0 +1,74 @@ +## 链接 + +【中等难度】3. Longest Substring Without Repeating Characters (最长不重复子串) + +https://leetcode.com/problems/longest-substring-without-repeating-characters/ + + +## 题目 + +Given a string **s**, find the longest palindromic substring in **s**. You may assume that the maximum length of **s** is 1000. + +**Example:** + +``` +Input: "babad" + +Output: "bab" + +Note: "aba" is also a valid answer. + +``` + +**Example:** + +``` +Given a string, find the length of the longest substring without repeating characters. + +Examples: + +Given "abcabcbb", the answer is "abc", which the length is 3. + +Given "bbbbb", the answer is "b", with the length of 1. + +Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring. +``` + +*Tags: Hash Table, Two Pointers* + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/03/note_Josan.md b/leetcode/03/note_Josan.md new file mode 100644 index 0000000..9b886e5 --- /dev/null +++ b/leetcode/03/note_Josan.md @@ -0,0 +1,97 @@ +## 链接 + +【中等难度】3. Longest Substring Without Repeating Characters (最长不重复子串) + +https://leetcode.com/problems/longest-substring-without-repeating-characters/ + + +## 题目 + +Given a string **s**, find the longest palindromic substring in **s**. You may assume that the maximum length of **s** is 1000. + +**Example:** + +``` +Input: "babad" + +Output: "bab" + +Note: "aba" is also a valid answer. + +``` + +**Example:** + +``` +Given a string, find the length of the longest substring without repeating characters. + +Examples: + +Given "abcabcbb", the answer is "abc", which the length is 3. + +Given "bbbbb", the answer is "b", with the length of 1. + +Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring. +``` + +*Tags: Hash Table, Two Pointers* + +## 释义 + +最长不重复子串 + + +## 补充描述 + +运用动态规划进行求解。 +dp[i]是指字符串从头到s[i]所找到的最长无重复子字符串长度。因此,答案dp[s.size()-1]就是所要的结果。期间用到了辅助数组标记访问位。 +时间复杂度为O(n*n)。 + + + +## 代码 + +```C++ +int flag[128] = { 0 }; +int getMax(int x, int y) +{ + return x > y?x:y; +} +void init(int* flag, int num) +{ + for(int i = 0; i != num; ++i) + { + flag[i] = 0; + } +} +class Solution +{ + public: + int lengthOfLongestSubstring(string s) + { + if(s.size() == 0) { return 0; } + vector dp(s.size(), 1); + for(int i = 1; i != s.size(); ++i) + { + int j = i; + int len = 0; + //向前开始查找,找到以s[i]结尾的最长无重复子序列 + for(; (j >= 0) && (flag[s[j]] == 0); --j) + { + flag[s[j]] = 1; + ++len; + } + dp[i] = getMax(dp[i - 1], len); + init(flag, 128); + } + return dp[s.size() - 1]; + } +}; +``` + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/03/note_leakey.md b/leetcode/03/note_leakey.md new file mode 100644 index 0000000..49c77a4 --- /dev/null +++ b/leetcode/03/note_leakey.md @@ -0,0 +1,109 @@ +## 链接 + +【中等难度】3. Longest Substring Without Repeating Characters (最长不重复子串) + +https://leetcode.com/problems/longest-substring-without-repeating-characters/ + + +## 题目 + +Given a string **s**, find the longest palindromic substring in **s**. You may assume that the maximum length of **s** is 1000. + +**Example:** + +``` +Input: "babad" + +Output: "bab" + +Note: "aba" is also a valid answer. + +``` + +**Example:** + +``` +Given a string, find the length of the longest substring without repeating characters. + +Examples: + +Given "abcabcbb", the answer is "abc", which the length is 3. + +Given "bbbbb", the answer is "b", with the length of 1. + +Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring. +``` + +*Tags: Hash Table, Two Pointers* + +## 释义 + + + + + + +## 补充描述 +A similar python code: +```python +class Solution(object): + def lengthOfLongestSubstring(self, s): + """ + :type s: str + :rtype: int + """ + sLen = len(s) + if sLen <= 1: return sLen # s is shorter than 2 letters + subStrLen, p1, p2 = 0, 0, 1 # use 2 pointers + while p2 < sLen and subStrLen < 95: + for p2 in xrange(p1, sLen): + if s[p2] in s[p1:p2]: + break + else: + p2 += 1 + subStrLen = max(p2 - p1, subStrLen) + p1 += 1 + return subStrLen +``` + + + + + +## 代码 + + + + + + +```c++ +class Solution { +public: + int lengthOfLongestSubstring(string s) { + int sLen = s.size(), subStrLen = 0, p1 = 0, p2 = 1; + if (sLen <= 1) + return sLen; + string subStr; + while (p2 < sLen && subStrLen < 95){ + for (p2 = p1; p2 < sLen; p2++){ + subStr.assign(s, p1, p2 - p1); //substr is s[p1:p2] + if (subStr.find(s[p2]) != -1) // s[p2] in substr + break; + } + subStrLen = max(p2 - p1, subStrLen); + p1++; + } + return subStrLen; + }; +}; + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/04/note.md b/leetcode/04/note.md new file mode 100644 index 0000000..42b09db --- /dev/null +++ b/leetcode/04/note.md @@ -0,0 +1,65 @@ +## 链接 + +4.Median of Two Sorted Arrays(Hard) + +## 题目 + +There are two sorted arrays **nums1** and **nums2** of size m and n respectively. + +Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). + +**Example 1:** + +``` +nums1 = [1, 3] +nums2 = [2] + +The median is 2.0 + +``` + +**Example 2:** + +``` +nums1 = [1, 2] +nums2 = [3, 4] + +The median is (2 + 3)/2 = 2.5 +``` + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/04/note_bajdcc.md b/leetcode/04/note_bajdcc.md new file mode 100644 index 0000000..77072a8 --- /dev/null +++ b/leetcode/04/note_bajdcc.md @@ -0,0 +1,174 @@ +## 链接 + +4.Median of Two Sorted Arrays(Hard) + +## 题目 + +There are two sorted arrays **nums1** and **nums2** of size m and n respectively. + +Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). + +**Example 1:** + +``` +nums1 = [1, 3] +nums2 = [2] + +The median is 2.0 + +``` + +**Example 2:** + +``` +nums1 = [1, 2] +nums2 = [3, 4] + +The median is (2 + 3)/2 = 2.5 +``` + +## 释义 + +将两个有序数列进行归并,找到其中位数。 + +先计算中位数: + +- 对总长n为奇数而言,中位数位置为n/2 +- 对总长n为偶数而言,中位数位置为(n-1)/2和(n-1)/2+1 + +问题在于如何求出指定位置的数。 + +### 特例 + +特例肯定有,想一想: + +- 其中一个数列为空,那么问题简单,在另一个数列中找即可 +- 一个数列的最大值小于另一数列的最小值,即数列1最末位小于数列2最前位,这时将数列1和2看作整体,再进行查找 + +### 另外情况 + +这时只能从前面开始一个个比较。设当前需要找到第index位。 + +分别用两个指针记录当前数列1和2的位置。哪边的值较小,就将相应的位置前进一位,index递减。不断循环。 + +什么时候跳出循环: + +- 某个数列被遍历到末尾了,这时只需要根据剩余的index在另外一个数列中查找即可 +- index为-1了,即相应的位置已被找到 + +下面有几种情况: + +- 其中一个数列遍历到末尾。若此时index为-1,那么位置就是这个数列的最末位,如果是奇数(中位数只要1位),就直接返回了;如果是偶数,就算上另一个数列的当前位置。若此时index不为-1,那么说明还要再往前面找几位,那么已遍历完的那个数列就out了,接下来只要在另一数列中查找即可。 +- 若不是上面的情况,就是最典型的情况了。先根据first知道上一个值是在哪一个数列中,然而找出这个值num[ptr-1],为什么要减一呢,这是因为在while循环中ptr需要向前移一位。如果是奇数,那么直接返回这个值;如果是偶数,那需要找出下一个值,下一个值在当前值后面一位和另外一数列当前位置中以较小值选择出来。 + +为什么这题难度为hard,我想不是因为思路想不到(归并),而是因为其中的步骤很烦,什么+1什么-1还要各种判断。 + +当然,还有可以优化的地方。如其中一数列元素只有一个,那么归并就变成了二分插入,能节省时间。 + + +## 补充描述 + +83.14% https://leetcode.com/submissions/detail/89933853/ + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +#define MIN(a,b) (((a)<(b))?(a):(b)) + +class Solution { +public: + static double findIdx(const vector &nums1, const vector &nums2, int index, bool odd) + { + int len1 = nums1.size(), len2 = nums2.size(); + auto ptr1 = 0, ptr2 = 0; + if (len1 == 0) + { + return odd ? nums2[index] : ((nums2[index] + nums2[index + 1]) / 2.0); + } + if (len2 == 0) + { + return odd ? nums1[index] : ((nums1[index] + nums1[index + 1]) / 2.0); + } + if (nums1.back() <= nums2.front()) + { + if (odd) + return index < len1 ? nums1[index] : nums2[index - len1]; + if (index < len1 - 1) + return (nums1[index] + nums1[index + 1]) / 2.0; + if (index > len1 - 1) + return (nums2[index - len1] + nums2[index - len1 + 1]) / 2.0; + return (nums1[index] + nums2[0]) / 2.0; + } + if (nums2.back() <= nums1.front()) + { + if (odd) + return index < len2 ? nums2[index] : nums1[index - len2]; + if (index < len2 - 1) + return (nums2[index] + nums2[index + 1]) / 2.0; + if (index > len2 - 1) + return (nums1[index - len2] + nums1[index - len2 + 1]) / 2.0; + return (nums2[index] + nums1[0]) / 2.0; + } + auto first = true; + while (ptr1 < len1 && ptr2 < len2 && index-- >= 0) + { + first = nums1[ptr1] <= nums2[ptr2]; + first ? ptr1++ : ptr2++; + } + if (index == -1) + { + if (ptr1 == len1) + { + return odd ? nums1.back() : (nums2[ptr2] + nums1.back()) / 2.0; + } + if (ptr2 == len2) + { + return odd ? nums2.back() : (nums1[ptr1] + nums2.back()) / 2.0; + } + } + if (ptr1 == len1) + { + return odd ? nums2[ptr2 + index] : (nums2[ptr2 + index] + nums2[ptr2 + index + 1]) / 2.0; + } + if (ptr2 == len2) + { + return odd ? nums1[ptr1 + index] : (nums1[ptr1 + index] + nums1[ptr1 + index + 1]) / 2.0; + } + if (first) + { + if (odd) + return nums1[ptr1 - 1]; + return (nums1[ptr1 - 1] + MIN(nums1[ptr1], nums2[ptr2])) / 2.0; + } + if (odd) + return nums2[ptr2 - 1]; + return (nums2[ptr2 - 1] + MIN(nums2[ptr2], nums1[ptr1])) / 2.0; + } + + double findMedianSortedArrays(vector &nums1, vector &nums2) + { + auto count = nums1.size() + nums2.size(); + auto idx = (count - 1) / 2; + return findIdx(nums1, nums2, idx, count % 2 == 1); + } +}; + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/05/note.md b/leetcode/05/note.md new file mode 100644 index 0000000..ef4d48a --- /dev/null +++ b/leetcode/05/note.md @@ -0,0 +1,68 @@ +## 链接 + +【中等难度】5. Longest Palindromic Substring (最长回文子串) + +https://leetcode.com/problems/longest-palindromic-substring/ + + +## 题目 + +Given a string **s**, find the longest palindromic substring in **s**. You may assume that the maximum length of **s** is 1000. + +**Example:** + +``` +Input: "babad" + +Output: "bab" + +Note: "aba" is also a valid answer. + +``` + +**Example:** + +``` +Input: "cbbd" + +Output: "bb" +``` + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/05/note_Josan.md b/leetcode/05/note_Josan.md new file mode 100644 index 0000000..c8973ab --- /dev/null +++ b/leetcode/05/note_Josan.md @@ -0,0 +1,150 @@ +## 链接 + +【中等难度】5. Longest Palindromic Substring (最长回文子串) + +https://leetcode.com/problems/longest-palindromic-substring/ + + +## 题目 + +Given a string **s**, find the longest palindromic substring in **s**. You may assume that the maximum length of **s** is 1000. + +**Example:** + +``` +Input: "babad" + +Output: "bab" + +Note: "aba" is also a valid answer. + +``` + +**Example:** + +``` +Input: "cbbd" + +Output: "bb" +``` + +## 释义 + +最长回文子串 + + +## 补充描述 + +自己采用的是Brute Force,然后通过不断优化算法,强行AC。一次次优化的过程,真的很有成就感。 +思路很简单,就是采用两指针,从尾开始判别,如果是回文数,哪肯定是那次循环当作最长的回文子字符串,因此直接break;进入下个循环。 + + + + +## 代码 + +一开始程序如下:这些都会出现LTE错误,主要是测试用例给的string很大。 + +```c++ +class Solution +{ + public: + string longestPalindrome(string s) + { + if(s.size() == 0) { return{}; } + int max = 0; + string res; + for(int i = 0; i != s.size(); ++i) + { +//由于j每次都是查看最后一个位置,其实只需要从等于s[i]的最后一个位置开始 + for(auto j = s.size(); j != i; --j) + { + if(isPalindrome(s, i, j)) + { + if(j - i > max) + { + max = j - i; +//可以不需要每次取出substr,可以直接记录起始位置就行;因为有个max,所以可以就记开始位置就好 + res = s.substr(i, j - i); + } + break; + } + } + } + return res; + } + //这个可以优化,不需要全部倒序就能判别是否是回文字符串 + bool isPalindrome(string s, int beg, int end) + { + string tem = s.substr(beg, end - beg); + reverse(tem.begin(), tem.end()); + return s.substr(beg, end - beg) == tem?true:false; + } +}; + +之后,改为 +//NOTE:对于字符串的取值,可以直接s[beg],这样显得很整洁,虽然也是符号重载为迭代器实现的 +bool isPalindrome(string s, int beg, int end) + { + while((end > beg) && *(s.begin() + beg) == *(s.begin() + end - 1)) + { + ++beg; + --end; + } + if(end > beg) return false; + else + { + return true; + } + } +``` +通过几次优化,可以勉强通过程序,不过时间花费比较大,509ms. + +```c++ +class Solution +{ + public: + string longestPalindrome(string s) + { + if(s.size() == 0) { return{}; } + int max = 0; + int beg = 0; + for(int i = 0; i != s.size(); ++i) + { + for(auto j = s.size(); j != i; --j) + { + j = s.find_last_of(s[i], j); + //肯定会找到j的,最坏的情况j==i;对于找到的子字符串如果长度<=max,那么直接跳出循环 + if(j + 1 - i <= max) { break; } + if(isPalindrome(s, i, j + 1)) + { + max = j + 1 - i; + beg = i; + break; + } + } + } + return s.substr(beg, max); + } + bool isPalindrome(string s, int beg, int end) + { + while((end > beg) && s[beg] == s[end - 1]) + { + ++beg; + --end; + } + if(end > beg) return false; + else + { + return true; + } + } +}; +``` + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/05/note_bajdcc.md b/leetcode/05/note_bajdcc.md new file mode 100644 index 0000000..7d0cc36 --- /dev/null +++ b/leetcode/05/note_bajdcc.md @@ -0,0 +1,211 @@ +## 链接 + +【中等难度】5. Longest Palindromic Substring (最长回文子串) + +https://leetcode.com/problems/longest-palindromic-substring/ + + +## 题目 + +Given a string **s**, find the longest palindromic substring in **s**. You may assume that the maximum length of **s** is 1000. + +**Example:** + +``` +Input: "babad" + +Output: "bab" + +Note: "aba" is also a valid answer. +``` + +**Example:** + +``` +Input: "cbbd" + +Output: "bb" +``` + + + +## 释义 + +求给定串的最长回文子串 + +### 简单思路 + +从左往右找回文串,最后给个最长的。 + +简单方法不简单。。怎么找回文串是个问题,从边上往中间找肯定不行,回文串的特点是两边对称,所以应该从对称方面着手。 + +### 优化思路 + +首先,一个回文串的字符频度应该是:中点频度最低为1,其他字符频度最低为2。 + +那么,**如果串中有频度是1的字符,它肯定位于回文串的中心,不然就不属于任何回文串**。 + +因此,按频度可以筛选掉一定量的多余字符,将母串进行**分割**。分割的好处是**子串有界**。 + +最懒方法:遍历整串,从中心向两侧扩张并做比较,取得长度,最后返回最大长度所在的串。 + +优化: + +- 在遍历整串过程中,最大长度maxlen会**时刻增加**,那么,当分割后的**有界子串**长度小于最大长度maxlen时,就不需要再去判断了。 +- 如果串的某个连续子串(len>=2)它们的频度都是1,那么它们就**不属于任何回文串**,可以快速剔除,节省时间。这是关键。 +- 其他方法还没想到,欢迎补充。 + +## 补充描述 + +debug两天,time=9ms https://leetcode.com/submissions/detail/87484290/ + +代码是为了验证思路是正确的。不得不吐槽leetcode的test case了,它对代码中的优化方法视而不见 :( + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + +#include + +using namespace std; + +class Solution { + int count[256]; + +public: + string longestPalindrome(string str) { + int start = 0, end = str.length() - 1; + if (longestPalindromePartition(str.c_str(), start, end, 1) > 1) { + return str.substr(start, end - start + 1); + } else { + return str.substr(0, end < start ? 0 : 1); + } + } + + int longestPalindromePartition(const char *str, int &start, int &end, int maxLen) { + if (end - start + 1 <= maxLen) + return 1; + int maxStart, maxEnd, len = maxLen; + int reserve = (maxLen + 1) / 2; + int reserveEnd = end - reserve + 1; + for (int i = start + reserve - 1, j, k; i <= reserveEnd; ++i) { + if (str[i] == str[i + 1]) { + for (j = i + 1, k = 1; i - k >= start && j + k <= end; ++k) { + if (str[i - k] != str[j + k]) + break; + } + k--; + if (j - i + 1 + k * 2 > len) { + len = j - i + 1 + k * 2; + reserve = (len + 1) / 2; + reserveEnd = end - reserve + 1; + maxStart = i - k; + maxEnd = j + k; + } + } + for (j = reserve; j > 0; --j) { + if (str[i - j] != str[i + j]) + break; + } + if (j == 0) { + for (j = reserve + 1; i - j >= start && i + j <= end; ++j) { + if (str[i - j] != str[i + j]) + break; + } + reserve = --j; + reserveEnd = end - reserve; + if (j * 2 + 1 > len) { + len = j * 2 + 1; + maxStart = i - j; + maxEnd = i + j; + } + } + } + if (maxLen < len) { + start = maxStart; + end = maxEnd; + return len; + } + return 1; + } + + int longestPalindrome(const char *str, int &start, int &end) { + if (start == end) + return 1; + for (int i = 0; i <= 26; ++i) { + count['a' + i] = 0; + } + int len = end - start + 1; + for (int i = start; i <= end; ++i) { + count[str[i]]++; + } + auto dups = new int[len]; + int dupCount = 0; + for (int i = start; i <= end; ++i) { + dups[i] = count[str[i]] > 1 ? (dupCount++, 1) : 0; + if (dups[i] == len) + return len; + } + int tmpStart = -1, tmpEnd = -1, maxStart = -1, maxEnd = -1, tmpLen, maxLen = 1; + for (int i = start; i <= end; ++i) { + if (dups[i]) { + tmpStart = i++; + for (; i <= end; ++i) { + if (!dups[i]) { + tmpEnd = i - 1; + break; + } + } + if (i-- > end) { + tmpEnd = end; + } + if ((tmpLen = longestPalindromePartition(str, tmpStart, tmpEnd, maxLen)) > maxLen) { + maxLen = tmpLen; + maxStart = tmpStart; + maxEnd = tmpEnd; + } + } else { + tmpStart = i; + for (; i <= end; ++i) { + if (dups[i]) { + tmpEnd = i - 1; + break; + } + } + if (i-- > end) { + tmpEnd = end; + } + if (tmpStart == tmpEnd) { + while (tmpStart >= start && tmpEnd <= end && str[--tmpStart] == str[++tmpEnd]); + tmpLen = (--tmpEnd) - (++tmpStart) + 1; + if (tmpLen > maxLen) { + maxLen = tmpLen; + maxStart = tmpStart; + maxEnd = tmpEnd; + } + } + } + } + start = maxStart; + end = maxEnd; + delete[]dups; + return maxLen; + } +}; +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/05/note_leakey.md b/leetcode/05/note_leakey.md new file mode 100644 index 0000000..2b4b0ea --- /dev/null +++ b/leetcode/05/note_leakey.md @@ -0,0 +1,88 @@ +## 链接 + +【中等难度】5. Longest Palindromic Substring (最长回文子串) + +https://leetcode.com/problems/longest-palindromic-substring/ + + +## 题目 + +Given a string **s**, find the longest palindromic substring in **s**. You may assume that the maximum length of **s** is 1000. + +**Example:** + +``` +Input: "babad" + +Output: "bab" + +Note: "aba" is also a valid answer. + +``` + +**Example:** + +``` +Input: "cbbd" + +Output: "bb" +``` + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ +class Solution { +public: + string longestPalindrome(string s) { + int sLen = s.length(), maxLen = 0, maxStart = 0; + int pi = 0, pl = 0, pr = 0, subLen = 0; + while (pi <= sLen - maxLen / 2){ + pl = pr = pi; + while (pr < sLen - 1 && s[pr + 1] == s[pr]) + pr++; + pi = pr + 1; + while (pl > 0 && pr < sLen - 1 && s[pr + 1] == s[pl - 1]){ + pl--; + pr++; + } + subLen = pr - pl + 1; + if (maxLen < subLen){ + maxLen = subLen; + maxStart = pl; + } + } + return s.substr(maxStart, maxLen); + } +}; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/06/note.md b/leetcode/06/note.md new file mode 100644 index 0000000..9927bc9 --- /dev/null +++ b/leetcode/06/note.md @@ -0,0 +1,48 @@ +## + + +https://leetcode.com/problems/zigzag-conversion/ + + +## Ŀ + + + + + +## + + + + + + +## + + + + + + +## + + + + + + +```c++ + +//棬Ըؼ + + + +``` + + + +## + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 뱣άӣԱ˲лл \ No newline at end of file diff --git a/leetcode/06/note_BigBrother007.md b/leetcode/06/note_BigBrother007.md new file mode 100644 index 0000000..e30fb1d --- /dev/null +++ b/leetcode/06/note_BigBrother007.md @@ -0,0 +1,63 @@ +## 链接 + + +https://leetcode.com/problems/zigzag-conversion/ + + +## 题目 + + + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +string result; + vector svec(numRows); + int length = s.length(); + if(numRows == 1) + return s; + for (int i = 0; i < length ; ++i) + { + //这个公式有点二,把i 一次变换为 0, 1, ... numRows-1, numRows-2, ... 0, ... + int j = abs(abs(i % (2 * numRows - 2)- numRows + 1) - numRows + 1); + svec[j] += s[i]; + } + for (int i = 0; i < numRows; ++i) + { + result += svec[i]; + } + return result; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/06/note_Josan.md b/leetcode/06/note_Josan.md new file mode 100644 index 0000000..37de60c --- /dev/null +++ b/leetcode/06/note_Josan.md @@ -0,0 +1,180 @@ +## 链接 + + +https://leetcode.com/problems/zigzag-conversion/ + + +## 题目 + +The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) + +P A H N +A P L S I I G +Y I R +And then read line by line: "PAHNAPLSIIGYIR" +Write the code that will take a string and make this conversion given a number of rows: + +string convert(string text, int nRows); +convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR". + +```c++ +class Solution { +public: + string convert(string s, int numRows) { + + } +}; +``` + +## 释义 + + + + + + +## 补充描述 + +一开始认为题目很简单,但是实际操作起来,发现自己的思路实现起来并没有那么简单。似乎这种感觉经常会出现。所以,不能眼高手低,一定要实现出来,绝不能想当然。 +思路: +首先,将zigzag图案的每行的列数算出来;如下, + +```c++ +P   A   H   N ………………………………………… col[0]=4 +A P L S I I G ………………………………………… col[1]=7 +Y I R ………………………………………… col[2]=3 +``` + +然后计算结果res;依次从每行开始遍历,然后对于每行的每一列进行遍历,运用相应的行列对应公式就可以得出结果。 +总评:对应公式比较复杂,期间调试很久。这真是一个糟糕的算法。 + + +## 自己的收获 + +对边界条件(Boundary Conditions)加深理解 + + +自己写的程序,一开始没有考虑边界条件。总是,直接提交,然后再看通不过的测试案例,然后再修改。虽然最后也能通过,但是在CCF认证考试,浙大的PAT考试,找工作的机试都是只能提交代码的。偶尔的系统还会告诉你,这个程序有没有全部通过测试案例,但是几乎全不会像LeetCode这么人性化还给你错误的案例。因此,必须对此加以重视,否则要找不到工作的节奏。 +总结一下:这次犯的错误。 +边界条件,主要就是对输入的把控。 + + +如果程序中,有除法运算,一定要记得考虑是否除数为0的情况。 + + +对于string,考虑size()为0的情况。对于int,考虑为0 以及正负数的情况。 + + +本题,没有考虑到负数的情况,说明我的程序还是有漏洞的,需要重视。别人的程序就有考虑。 + + +对于string部分的初始化、size以及capacity理解更深。 + +```C++ +string a(10); //no exist such initialization but vector a(10) is okay +string a(10,’\0’) //but you can do like this +对于一个string a;需要时刻考虑他的size以及capacity。 +eg: string a; + a.reserve(10); //PS: reserve()的效果是只增不减 + a[6]=’x’; //就是会报错的,reserve只是改变了capacity,而不是size +``` + + +## 代码 + +分享一个连我自己都觉得呕心的代码。 + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + +class Solution +{ + public: + string convert(string s, int numRows) + { + if (s.size() == 0) + { + return string(); + } + else if (numRows == 1) + { + return string(s.begin(), s.end()); + } + + int sz = s.size(); + string res(sz,'\0'); + + vector col(numRows, 0); + + + + col[ 0 ] = ( sz - 1 ) / ( (numRows << 1) - 2 ) + 1; + + for (int i = 1; i < numRows - 1; ++i) + { + if (sz - ( ( numRows - 1 )*(( col[ 0 ] - 1 ) << 1) + 1 + i ) < 0) + { + col[ i ] = (col[ 0 ]-1) << 1; + } + else if (sz - ( ( numRows - 1 )*(( col[ 0 ] - 1 ) << 1) + (numRows << 1) - i - 1 ) < 0) + { + col[ i ] = (col[ 0 ] << 1) - 1; + } + else + { + col[ i ] = col[ 0 ]<< 1; + } + } + + //compute col[numRows-1] + if (sz - ( ( numRows - 1 )*(( col[ 0 ] - 1 ) << 1) + numRows ) < 0) + { + col[ numRows - 1 ] = col[ 0 ] - 1; + } + else + { + col[ numRows - 1 ] = col[ 0 ]; + } + + + for (int index = 0, i = 0; i < numRows&&index != sz; ++i) + { + if (i == 0 || i == numRows - 1) + { + for (int j = 0; j != col[ i ]; ++j) + { + + res[ index++ ] = s[ ( ( ( numRows - 1 )*j ) << 1 ) + i ]; + } + } + else + { + for (int j = 0; j != col[ i ]; ++j) + { + if (j % 2 == 0) + { + res[ index++ ] = s[ ( j >> 1 )*( ( numRows - 1 ) << 1 ) + i ]; + } + else + { + res[ index++ ] = s[ ( j >> 1 )*( ( numRows - 1 ) << 1 ) + ( numRows << 1 ) - i - 2 ]; + } + } + } + } + return res; + } +}; +``` + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/06/note_Yac836.md b/leetcode/06/note_Yac836.md new file mode 100644 index 0000000..02bb284 --- /dev/null +++ b/leetcode/06/note_Yac836.md @@ -0,0 +1,53 @@ +## 链接 + + +https://leetcode.com/problems/zigzag-conversion/ + +## 解题思路 + +这道题目让按`z`型输出。根据样例,我们可以得出实现方法。 + +1. 有几行,我们就需要几个字符串记录每一行都是什么字符。我们可以采用`vector`来记录每一行都有什么字符 +2. 遍历原字符串,将每个字符,记录到他应该属于的字符串中。 +3. 将每个字符串连接起来 + + + + +## 代码 + + + + + + +```c++ +string convert(string s, int numRows) { + if (s.empty()) + return ""; + vector tres(numRows); + vector::size_type index; + string res; + auto len = s.size(); + for (index = 0; index < len; ) { + for (int i = 0; i < numRows && index < len; i++) + tres[i] = tres[i] + s[index++]; + for (int j = numRows - 2; j > 0 && index < len; j--) + tres[j] = tres[j] + s[index++]; + } + for (const string e : tres) + res = res + e; + + return res; +} + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/06/note_bajdcc.md b/leetcode/06/note_bajdcc.md new file mode 100644 index 0000000..b4c9d67 --- /dev/null +++ b/leetcode/06/note_bajdcc.md @@ -0,0 +1,103 @@ +## 链接 + +https://leetcode.com/problems/zigzag-conversion/ + +## 题目 + +The string `"PAYPALISHIRING"` is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) + + P A H N + A P L S I I G + Y I R +And then read line by line: `"PAHNAPLSIIGYIR"` +Write the code that will take a string and make this conversion given a number of rows: + + string convert(string text, int nRows); +`convert("PAYPALISHIRING", 3)` should return `"PAHNAPLSIIGYIR"`. + +## 释义 + +已知输入为字串A和数字n,求输出为字串B。即B=fun(A,n)。 + +A和B之间存在映射关系f,即B[i]=A[f(i)],问题在于求映射f。 + + 0 4 8 + 1 3 5 7 9 + 2 6 + +以上述为例,输入A=0123456789,n=3。 + +可以看出:一共n行。 + +- 第一行:起始行,以0开始,公差为4。 +- 第二行:以1开始,公差为4,公差之内包括两个数字。 +- 第三行:结束行,以2开始,公差为4。 + +经过不断推导,最终得出映射关系。 + +若串为A,长度为len,行数为numRows,则关系为: + +- 第一行,从0开始,公差d=(numRows - 1)*2,下标超过len-1无效。 +- 第二行到倒数第二行,设该行是k行,则该行从k开始,公差为d,公差内包括两个数字,第二个数字=第一个数字+d- (k*2),下标越界作废。 +- 最后一行,同第一行。 + +注:该法不用把zigzag矩阵罗列出来,直接写于结果当中。 + +## 补充描述 + +提交:https://leetcode.com/submissions/detail/87277753/ + +用时:12ms,beat:96%(运气好) + + +## 代码 + + + + +```c++ +#include +#include + +using namespace std; + +class Solution { +public: + string convert(string s, int numRows) { + int n = (int) s.length(); + auto arr = new char[n]; + if (numRows <= 1) { + return s; + } else { + int index, add, start; + index = start = 0; + add = (numRows - 1) << 1; + for (int i = start++; i < n; i += add) { + arr[index++] = s[i]; + } + for (int k = 1, j; k < numRows - 1; ++k) { + for (int i = start++; i < n; i += add) { + arr[index++] = s[i]; + if (((j = i + add - (k << 1)) < n)) { + arr[index++] = s[j]; + } + } + } + for (int i = start; i < n; i += add) { + arr[index++] = s[i]; + } + } + decltype(s) result(arr, s.length()); + delete[]arr; + return result; + } +}; +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/06/note_leakey.md b/leetcode/06/note_leakey.md new file mode 100644 index 0000000..7c22fdc --- /dev/null +++ b/leetcode/06/note_leakey.md @@ -0,0 +1,108 @@ +## 链接 + + +https://leetcode.com/problems/zigzag-conversion/ + + +## 题目 + + + + + +## 释义 + + + + + + +## 补充描述 +Another python solution: +```python +class Solution(object): + def convert(self, s, numRows): + """ + :type s: str + :type numRows: int + :rtype: str + """ + lens = len(s) + if lens <= numRows or numRows <= 1: + return s + else: + strre = "" + lenstr = (numRows - 1) * 2 + i = j = k = m = 0 + lenstrre = 0 + while lenstrre < lens: + strre = strre + s[j] + lenstrre += 1 + if not j % (lenstr / 2): + j += lenstr + else: + m += 1 + k = lenstr - j if m == 1 else lenstr + k + if k >= lens: + i += 1 + j = i + m = 0 + else: + strre = strre + s[k] + lenstrre += 1 + j += lenstr + if j >= lens: + i += 1 + j = i + m = 0 + return strre +``` + + + + + +## 代码 + + + + + + +```c++ + +class Solution { +public: + string convert(string s, int numRows) { + if (numRows <= 1 || numRows >= s.length()) + return s; + string result = ""; + int maxStep = numRows * 2 - 2; + for (int i = 1; i <= numRows; i++){ + int j = i - 1; + int step = (i < numRows) ? (numRows - i) * 2 : maxStep; + while (j < s.length()) { + result += s[j]; + if (result.length() == s.length()) + return result; + j += step; + if (step < maxStep) { + step = maxStep - step; + } + } + } + return result; + } +}; + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/07/note_Josan.md b/leetcode/07/note_Josan.md new file mode 100644 index 0000000..a74b18b --- /dev/null +++ b/leetcode/07/note_Josan.md @@ -0,0 +1,59 @@ +## 链接 + + +https://leetcode.com/problems/reverse-integer/ + + +## 题目 + +Reverse digits of an integer. + +Example1: x = 123, return 321 +Example2: x = -123, return -321 + +```c++ +class Solution { +public: + int reverse(int x) { + + } +}; +``` + +## 释义 + +翻转一个整数,如果是123,结果就是321;如果输入是-123,结果就是-321。 + +## 补充描述 + +主要的注意项就是12345 67899,翻转之后就是99876 54321;会发生溢出的情况。 + + +## 代码 + + + + + + +```c++ + +class Solution { +public: + int reverse(int x) { + long long r = 0; + while (x) r = r*10 + x%10, x /= 10; + return (int(r) == r) * r; +} +}; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/07/note_Yac836.md b/leetcode/07/note_Yac836.md new file mode 100644 index 0000000..fd1c322 --- /dev/null +++ b/leetcode/07/note_Yac836.md @@ -0,0 +1,59 @@ +## 链接 + + +https://leetcode.com/problems/reverse-integer/ + + + + +## 思路 + +1. 将每位上的数字拿出来,存到`vector`中,从低位开始拿 +2. 再将每一位加起来 + + + + +## 代码 + + + + + + +```c++ +int reverse(int x) { + vector ivct; + //2147483647 + vector maxInt{ 2,1,4,7,4,8,3,6,4,7 }; + int flag = 1; + int res = 0; + if (x == 0 || x == -2147483647 - 1) + return 0; + if (x < 0) { + x = -x; + flag = -1; + } + while (x != 0) { + ivct.push_back(x % 10); + x = x / 10; + } + decltype(ivct.size()) len = ivct.size(); + if (len == 10) { + if (ivct > maxInt) + return 0; + } + for (decltype(ivct.size()) index = 0; index < ivct.size(); index++) + res = res * 10 + ivct[index]; + res = res * flag; + return res; +} +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/07/note_leakey.md b/leetcode/07/note_leakey.md new file mode 100644 index 0000000..c1c14a0 --- /dev/null +++ b/leetcode/07/note_leakey.md @@ -0,0 +1,58 @@ +## 链接 + + +https://leetcode.com/problems/reverse-integer/ + + +## 题目 + + + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { +public: + int reverse(int x) { + long long y = 0; + while (x) { + y = y * 10 + x % 10; + x /= 10; + } + return y < INT_MIN || y > INT_MAX ? 0 : y; + } +}; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/08/note_Josan.md b/leetcode/08/note_Josan.md new file mode 100644 index 0000000..b8f60e8 --- /dev/null +++ b/leetcode/08/note_Josan.md @@ -0,0 +1,131 @@ +## 链接 + + +https://leetcode.com/problems/string-to-integer-atoi/ + + +## 题目 + +Implement atoi to convert a string to an integer. + +Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. + +Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front. + +Update (2015-02-10): +The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button to reset your code definition. + +spoilers alert... click to show requirements for atoi. + +```C++ +class Solution { +public: + int myAtoi(string str) { + + } +}; +``` + +## 释义 + +将对应的String转换成相应的整数形式 + +## 补充描述 + +string format: [whitespace] [sign] [0] [x] [digits/letters] +凡是不符合这个格式的string都是非法的 + +## 代码 + +很简单,就是依次转存。但是,我测试不通过了4次,只考虑string为空的情况,其他情况都没有考虑。可见,对于程序的健壮性这点,以及程序测试这块,我的水平很差,需要继续不断注意训练。 + + +```c++ + + +class Solution +{ + public: + int myAtoi(string str) + { + long long res = 0; + if(0 == str.size()) + { + return res; + } + auto i = str.begin(); + //remove the whitespace + while(i != str.end() && isspace(*i)) + { + ++i; + } + if(i == str.end()) + { + return res; + } + bool flag = true; + int sign = 1; + for(; i != str.end(); ++i) + { + if(flag&&*i == '-') + { + sign = -1; + flag = false; + continue; + } + else if(flag&&*i == '+') + { + flag = false; + continue; + } + if(*i >= '0'&&*i <= '9') + { + res = res * 10 + (*i - '0'); + } + else + { + break; + } + if(res > INT_MAX) + { + break; + } + } + res = sign*res; + if(res > INT_MAX) + { + res = INT_MAX; + } + else if(res < INT_MIN) + { + res = INT_MIN; + } + return static_cast(res); + } +}; + + + +``` + + +再分享一个比较接近官方文件的代码,官方文件采用一个trick,就是pre-check技术,下面这个代码就是用了这个技术。 +```C++ +int myAtoi(string str) +{ + int ret = 0, sign = 1, i = str.find_first_not_of(' '), base = INT_MAX / 10; + if(str[i] == '+' || str[i] == '-') sign = str[i++] == '+' ?: -1; + while(isdigit(str[i])) + { + if(ret > base || (ret == base && str[i] - '0' > INT_MAX % 10)) return sign > 0 ? INT_MAX : INT_MIN; + ret = 10 * ret + (str[i++] - '0'); + } + return sign * ret; +} + +``` +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/08/note_Yac836.md b/leetcode/08/note_Yac836.md new file mode 100644 index 0000000..4304645 --- /dev/null +++ b/leetcode/08/note_Yac836.md @@ -0,0 +1,77 @@ +## 链接 + + +https://leetcode.com/problems/string-to-integer-atoi/ + + +## 解题思路 +1. 找出开始数字和结束数字然后装换 + +***注意*** +1. int 最小值 +2. 正负数 + + + +## 代码 + + + + + + +```c++ +int myAtoi(string str) { + int i = 0; + int flag = 0; + double res = 0; + int sign = 1; + for (auto c : str) { + if (!isdigit(c)) { + i++; + } + else + break; + } + int temp = i - 1; + for (int index = 0; index < temp; index++) { + if (isspace(str[index])) + continue; + else { + flag = 1; + break; + } + } + if (flag) + return 0; + if (i > 0) { + if (str[i - 1] == '+' || isspace(str[i - 1])) + sign = 1; + else if (str[i - 1] == '-') + sign = -1; + else + return 0; + } + for (decltype(str.size()) index = i; index < str.size(); index++) + if (isdigit(str[index])) + res = res * 10 + (str[index] - '0'); + else + break; + res = res * sign; + if (res > 2147483647) + return 2147483647; + // -2147483648 直接写 vs2015 会报错 codeblocks 不会 + if (res < -2147483647 - 1) + return -2147483647 - 1; + return res; +} + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/08/note_leakey.md b/leetcode/08/note_leakey.md new file mode 100644 index 0000000..4554f05 --- /dev/null +++ b/leetcode/08/note_leakey.md @@ -0,0 +1,64 @@ +## 链接 + + +https://leetcode.com/problems/string-to-integer-atoi/ + + +## 题目 + + + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { +public: + int myAtoi(string s) { + int i = 0, sign, MAX = 0; + long long val = 0; + for (i = 0; isspace(s[i]); i++); //remove spaces from left + sign = (s[i] == '-' ? -1 : 1); + if (s[i] == '+' || s[i] == '-') + i++; + for (val = 0; isdigit(s[i]); i++){ + val = 10 * val + (s[i] - '0'); + if (val > INT_MAX) + return (sign == 1 ? INT_MAX : INT_MIN); + } + return val * sign; + } +}; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/09/note_Josan.md b/leetcode/09/note_Josan.md new file mode 100644 index 0000000..85ddcb7 --- /dev/null +++ b/leetcode/09/note_Josan.md @@ -0,0 +1,97 @@ +## 链接 + + +https://leetcode.com/problems/palindrome-number/ + + +## 题目 + + +判断一个32位整型是否是回文数。 + + +## 补充描述 + +首先取出前后两个数字,然后比较这两个数字;之后,去掉这两个数字后,继续比较。这样可以防止出现溢出现象。 + + + + +## 代码 + +1、自己的程序: +```C++ +class Solution +{ + public: + bool isPalindrome(int x) + { + if(x < 0) return false; + if(x == 0) return true; + int digits = 0; + int tem = x; + digits = int(log10(x)); + tem = x; + while((digits > 0) && + (tem % 10) == (tem / int(pow(10, digits)))) + { + tem -= tem % 10 + (tem % 10)*int(pow(10, digits)); + tem /= 10; + digits -= 2; + } + return (digits <= 0)?true:false; + } +}; +``` + +2、别人的程序 +对自己程序的改进版 + +```C++ +class Solution +{ + public: + bool isPalindrome(int x) + { + if(x < 0) return false; + int d = 1; // divisor + while(x / d >= 10) d *= 10; + while(x > 0) + { + int q = x / d; // quotient + int r = x % 10; // remainder + if(q != r) return false; + x = x % d / 10; + d /= 100; + } + return true; + } +}; +``` + +这题最好的解题方法,一个只需要遍历一半,就可以 +```C++ +class Solution +{ + public: + bool isPalindrome(int x) + { +//一个边界条件都不能少 + if(x < 0 || (x != 0 && x % 10 == 0)) return false; + int sum = 0; + while(x > sum) + { + sum = sum * 10 + x % 10; + x = x / 10; + } + return (x == sum) || (x == sum / 10); + } +}; +``` + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/10/note.md b/leetcode/10/note.md new file mode 100644 index 0000000..220e116 --- /dev/null +++ b/leetcode/10/note.md @@ -0,0 +1,65 @@ +## 链接 + +10.Regular Expression Matching(Hard) + +## 题目 + +Implement regular expression matching with support for `'.'` and `'*'`. + +``` +'.' Matches any single character. +'*' Matches zero or more of the preceding element. + +The matching should cover the entire input string (not partial). + +The function prototype should be: +bool isMatch(const char *s, const char *p) + +Some examples: +isMatch("aa","a") → false +isMatch("aa","aa") → true +isMatch("aaa","aa") → false +isMatch("aa", "a*") → true +isMatch("aa", ".*") → true +isMatch("ab", ".*") → true +isMatch("aab", "c*a*b") → true +``` + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/10/note_bajdcc.md b/leetcode/10/note_bajdcc.md new file mode 100644 index 0000000..94c3eeb --- /dev/null +++ b/leetcode/10/note_bajdcc.md @@ -0,0 +1,290 @@ +## 链接 + +10.Regular Expression Matching(Hard) + +## 题目 + +Implement regular expression matching with support for `'.'` and `'*'`. + +``` +'.' Matches any single character. +'*' Matches zero or more of the preceding element. + +The matching should cover the entire input string (not partial). + +The function prototype should be: +bool isMatch(const char *s, const char *p) + +Some examples: +isMatch("aa","a") → false +isMatch("aa","aa") → true +isMatch("aaa","aa") → false +isMatch("aa", "a*") → true +isMatch("aa", ".*") → true +isMatch("ab", ".*") → true +isMatch("aab", "c*a*b") → true +``` + + + + +## 方法一:回溯法 + +这是最容易想到的方法。 + +设模式串为pat,要匹配的串为str。 + +如果pat和str当前全是字母,那就一位位匹配即可。但这里有难点,也就是pat的字母后面可能跟\*,这个\*非常的特殊。 + +比如a\*,它可以匹配连续的a,也可以什么都不匹配,这是比较难的地方。接触过编译原理就会知道,这个\*对应的是epsilon串,这使得整个状态机变成不确定的,不确定状态机的后果就是需要不断回溯。回溯其实可以避免,看方法二。 + +因此,**假如知道当前的字符,万一它后面跟了*呢?**所以,需要**向前看一个字符**,设为ahead。 + +思路就出来了。设遍历pat的指针为i,遍历str的指针为j。 + +- 假如当前字母是单纯的字母,即后面没有跟着\*,那么就比对pat[i]和str[j] +- 假如当前是单纯的匹配单字符".",后面没有跟着\*,那么不需要对比,i++ +- 特殊情况,即单纯字母"a~z"或是匹配单字符"."后面带了个\*,那么就进入回溯模式,递归调用isMatch并且j++,isMatch能返回真,那么匹配成功,否则继续匹配 +- 以上情况,若跳出循环时i和j都到了pat和str的末尾,则匹配成功 + +为了辨别当前字符的类型,用了查找数组patMap。 + +下面是代码,但还有另外一种形式即全递归的,由于两者功能相同,因此略。 + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { + enum Pat + { + OTHER = 0, + ALPHABET, + DOT, + STAR, + END + }; + Pat patMap[0xff] = { OTHER }; // map pattern character + +public: + Solution() + { + for (auto i = 'a'; i <= 'z'; i++) + { + patMap[i] = ALPHABET; // [a-z] + } + patMap['.'] = DOT; // . + patMap['*'] = STAR; // * + patMap['#'] = END; // # + } + + bool isMatch(string s, string p) { + return isMatchImpl(s.c_str(), p.c_str(), s.length(), p.length()); // add stop(look ahead) + } + + using pstr = const char *; + + bool isMatchImpl(pstr s, pstr p, int slen, int plen) { + if (plen == 0) + return slen == 0; + auto c = '$', next = p[0]; + auto pat = OTHER, nextPat = patMap[next]; // look ahead + auto j = 0, i = 0, prev = -1; + for (; i < plen && j <= slen;) + { + if (prev == i - 1) + { + c = next; + pat = nextPat; + next = i + 1 == plen ? '#' : p[i + 1]; + nextPat = patMap[next]; + prev = i; + } + else if (prev < i) + { + c = p[i]; + pat = patMap[c]; + next = i + 1 == plen ? '#' : p[i + 1]; + nextPat = patMap[next]; + prev = i; + } + switch (pat) + { + case OTHER: + throw "invalid character"; + break; + case ALPHABET: + switch (nextPat) + { + case OTHER: + throw "invalid character"; + break; + case ALPHABET: + case DOT: + case END: + if (c != s[j]) + return false; // [a-z] not match + i++; j++; + break; + case STAR: + if (c != s[j]) + i += 2; // [a-z]* not match, skip pattern [a-z]* + else + { + // [a-z]* match, got epsilon, backtracking + if (isMatchImpl(s + j, p + i + 2, slen - j, plen - i - 2)) + return true; + j++; + if (j == slen) + i += 2; + } + break; + default: + break; + } + break; + case DOT: + switch (nextPat) + { + case OTHER: + throw "invalid character"; + break; + case ALPHABET: + case DOT: + case END: + i++; j++; // match . + break; + case STAR: + // got epsilon, use backtracking + if (i + 1 == plen) + { + return true; // .* match all + } + if (isMatchImpl(s + j, p + i + 2, slen - j, plen - i - 2)) + return true; + j++; + if (j == slen) + i += 2; + break; + default: + break; + } + break; + case STAR: + throw "invalid character"; // single * + break; + default: + break; + } + } + return i == plen && j == slen; + } +}; + +``` + + + +## 方法二:动态规划法 + +由于方法一存在多余的回溯问题,因此要避免回溯,采用DP方法。 + +DP方法的优点:不需要递归(不复制string),思路清晰,由状态转移方程推导出(先逻辑验证,不易出错),效率高,其结果是简化的状态机 + +DP方法的缺点:推导过程复杂 + +二维DP的一般步骤: + +1. 两个相关变量的表述,须为数字,这里是原串和模式串的长度,同时也决定了dp表的大小以及算法的复杂度 +2. dp表的值类型,这里是bool +3. 根据题意总结规则 +4. 根据规则写出详尽的状态转移方程 +5. 在双重for循环中实现状态转移 +6. 返回dp表的最右下值 + +设模式串为pat,要匹配的串为str。因此dp数组的大小是(patlen+1) x (strlen+1),大小为子串的长度。 + +推导规则: + +1. 空串匹配空串:dp(0,0)=true +2. '.\*'组合匹配空串:消除'.\*'并匹配,dp(0,j)=dp(0,j-2) +3. '.\*'或'a\*'匹配:看上次结果dp(i-1,j),若真则真;若假则看dp(i,j-2) +4. 'a\*'匹配:看上次结果dp(i-1,j),若真则比较最新匹配位s(i-1)=p(j-2);若假则看dp(i,j-2) +5. 非'\*'匹配空串:dp(0,j)=false +6. '.'匹配:看上次结果dp(i-1,j-1) +7. 'a':看上次结果dp(i-1,j-1),同时比较最新匹配位s(i-1)=p(j-1) + +代码如下,耗时是回溯法的1/3左右。 + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { +public: + bool isMatch(string s, string p) { + int slen = s.length(), plen = p.length(); + // dp[i,j] -> str[0..i-1] 是否被 pat[0..j-1] 匹配 + vector> dp(slen + 1, vector(plen + 1, false)); + // 二重循环构建dp数组,按部就班 + // dp[i,j] -> pat[0..j-1] matches str[0..i-1] + dp[0][0] = true; // empty matches empty + for (auto i = 0; i <= slen; i++) + { + // 这里省略了j从0开始的部分,因为pat为空时,除非str为空否则匹配失败 + for (auto j = 1; j <= plen; j++) + { + if (p[j - 1] == '*') // '*'不应该在第一位,因此j>1 + { + // 当前为'*',这里情况稍显复杂 + if (p[j - 2] == '.') + { + if (i > 0 && dp[i - 1][j]) + // '.*' matches 'abc' => '.*' == 'ab' + dp[i][j] = true; + } + else + { + if (i > 0 && dp[i - 1][j]) + // 'a*' matches 'aa' => 'a*' == 'a' && 'a' == 'a' + dp[i][j] = s[i - 1] == p[j - 2]; + } + if (!dp[i][j]) // retry + // 'a.*' matches 'a' => 'a' == 'a' + dp[i][j] = dp[i][j - 2];; + } + else + { + // 当前pat[i]是[a-z]或者'.',则单字符匹配 + if (i == 0) + // 非空模式串不能匹配空串 + dp[0][j] = false; + else + { + if (p[j - 1] == '.') + { + // 当前为'.' + // 'a.' matches 'aa' => 'a' == 'a' + dp[i][j] = dp[i - 1][j - 1]; + } + else + { + // 当前为[a-z] + // 'ab' matches 'ab' => 'a' == 'a' && 'b' == 'b' + dp[i][j] = dp[i - 1][j - 1] && s[i - 1] == p[j - 1]; + } + } + } + } + } + return dp[slen][plen]; + } +}; +``` + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/12/note.md b/leetcode/12/note.md new file mode 100644 index 0000000..51fb2d2 --- /dev/null +++ b/leetcode/12/note.md @@ -0,0 +1,51 @@ +## 链接 + +【中等难度】12. Integer to Roman(数字转罗马文) + +https://leetcode.com/problems/integer-to-roman/ + + +## 题目 + +Given an integer, convert it to a roman numeral. + +Input is guaranteed to be within the range from 1 to 3999. + +*Tags: Hash Table or Syntax-directed Translation(Advanced)* + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/12/note_Josan.md b/leetcode/12/note_Josan.md new file mode 100644 index 0000000..7b03dab --- /dev/null +++ b/leetcode/12/note_Josan.md @@ -0,0 +1,84 @@ +## 链接 + +【中等难度】12. Integer to Roman(数字转罗马文) + +https://leetcode.com/problems/integer-to-roman/ + + +## 题目 + +Given an integer, convert it to a roman numeral. + +Input is guaranteed to be within the range from 1 to 3999. + +*Tags: Hash Table or Syntax-directed Translation(Advanced)* + +## 释义 + +题目很直白,就是数字转罗马数字 +## 补充描述 + + +使用了辅助数组进行求解。当然这个辅助数组具有一定的特征,可以使用函数进行求解。然而,我们一般还是用空间来换时间。 +这里使用了一个特征,就是789——对应罗马数字的(7【百位】+8【十位】+9【个位】)。 + + + + +## 代码 + + + + + + +```c++ + + +//辅助数组 +string str[4][10] = { + { "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" }, + { "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC" }, + { "", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM" }, + { "", "M", "MM", "MMM" } +}; + +class Solution +{ + public: + string intToRoman(int num) + { + if(num <= 0 || num > 3999) return string(); + + string res; +    //这样提前分配空间可以适当优化时间 + res.reserve(200); + + stack st; + + int digits = 0;//digits表示num的位数 + while(num) + { + st.push(num % 10); + num /= 10; + ++digits; + } + while(!st.empty()) + { + int temp = st.top(); + res += str[--digits][temp]; + st.pop(); + } + return res; + } +}; + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/12/note_leakey.md b/leetcode/12/note_leakey.md new file mode 100644 index 0000000..f4998da --- /dev/null +++ b/leetcode/12/note_leakey.md @@ -0,0 +1,93 @@ +## 链接 + +【中等难度】12. Integer to Roman(数字转罗马文) + +https://leetcode.com/problems/integer-to-roman/ + + +## 题目 + +Given an integer, convert it to a roman numeral. + +Input is guaranteed to be within the range from 1 to 3999. + +*Tags: Hash Table or Syntax-directed Translation(Advanced)* + +## 释义 + + + + + + +## 补充描述 +Similar python solution: +```python +class Solution(object): + def intToRoman(self, num): + """ + :type num: int + :rtype: str + :ref: http://www.cnblogs.com/dosxp/archive/2008/08/13/1266781.html + """ + hrom = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"] + trom = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"] + rom = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"] + intdex = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + hdic = dict(zip(intdex, hrom)) + tdic = dict(zip(intdex, trom)) + dic = dict(zip(intdex, rom)) + + rostr = "" + k = num // 1000 + num = num % 1000 + + h = num // 100 + num = num % 100 + + t = num // 10 + num = num % 10 + + rostr = "M"*k + hdic[h] + tdic[t] + dic[num] + return rostr + +``` + + + + + +## 代码 + + + + + + +```c++ + +class Solution { +public: // Use dict to convert 0 - 3999 to Roman + string intToRoman(int num) { + char* rom3[4] = {"", "M", "MM", "MMM"}; //0XXX - 3XXX + char* rom2[10] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}; //0XX - 9XX + char* rom1[10] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}; //0X - 9X + char* rom0[10] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}; //0 - 9 + string s; + s += rom3[num / 1000]; //X... + s += rom2[num % 1000 / 100]; //.X.. + s += rom1[num % 100 / 10]; //..X. + s += rom0[num % 10]; //...X + return s; + } +}; + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/13/note_Josan.md b/leetcode/13/note_Josan.md new file mode 100644 index 0000000..fd6ca88 --- /dev/null +++ b/leetcode/13/note_Josan.md @@ -0,0 +1,78 @@ +## 链接 + +https://leetcode.com/problems/roman-to-integer/ + +## 题目 + +将罗马数字转换为整形,输入范围是1-3999 + +## 释义 + +1-3999的罗马数,用到的符号和对应的十进制数如下: + +I → 1 + +V → 5 + +X → 10 + +L → 50 + +C → 100 + +D → 500 + +M → 1000 + + + +## 补充描述 + + + + +## 代码 + +利用hash进行快速读取,然后从头到尾因此遍历,如果第一次遍历的数,比接下来遍历的数小,则减掉第一次遍历的数值,否则加上。对于最后一位,则是直接加上相应的数值。 + +```c++ +class Solution +{ + public: + int romanToInt(string s) + { + map rmaMap = { + { 'I', 1 }, + { 'V', 5 }, + { 'X', 10 }, + { 'L', 50 }, + { 'C', 100 }, + { 'D', 500 }, + { 'M', 1000 } + }; + int res = 0; + for(string::size_type i = 0; i != s.size(); ++i) + { + auto j = i + 1; + int val = rmaMap[s[i]]; + if(j != s.size() && val < rmaMap[s[j]]) + { + res -= val; + } + else + { + res += val; + } + } + return res; + } +}; + +``` + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/14/note_Josan.md b/leetcode/14/note_Josan.md new file mode 100644 index 0000000..ba5127f --- /dev/null +++ b/leetcode/14/note_Josan.md @@ -0,0 +1,128 @@ +## 链接 + +[https://leetcode.com/problems/longest-common-prefix/](https://leetcode.com/problems/longest-common-prefix/) + +## 题目 + +题目是要求出一个string序列中,所有字符串共有的前缀。 + +比如 ["aa", "ab"], 那么结果就是"a" + +## 释义 + +N.A. + +## 补充描述 + + + +#自己的解题思路(纵向) + +依次比较每个字符串的相同序号的字符,如果都相同,比较下一个;如果不同,跳出循环。 + + +#别人的解题思路(横向) + +每两个字符串找出最长的公共子串,然后得出最长的公共子串。 + + +## 代码 + +1、自己的程序: +```C++ +class Solution +{ + public: + string longestCommonPrefix(vector& strs) + { + int n = strs.size(); + if(n == 0) return{}; + string res; + int min = INT_MAX; + for(int i = 0; i != n; ++i) + { + min = int((strs.begin() + i)->size()) < min + ?int((strs.begin() + i)->size()):min; + } + for(int i = 0; i < min; ++i) + { + int j = 1; + for(; j < n; ++j) + { + if(strs[j - 1][i] != strs[j][i]) + { + break; + } + } + if(j < n) { break; } + else + { + res.push_back(strs[0][i]); + } + } + return res; + } +}; +``` + +自己改进版,速度有所提升。去掉临时存储字符串的res,因为只需要最后一次取出就行。 +```C++ +class Solution +{ + public: + string longestCommonPrefix(vector& strs) + { + int n = strs.size(); + if(n == 0) return{}; + int min = INT_MAX; + for(int i = 0; i != n; ++i) + { + min = int((strs.begin() + i)->size()) < min + ?int((strs.begin() + i)->size()):min; + } + int i = 0; + for(; i < min; ++i) + { + int j = 1; + for(; j < n; ++j) + { + if(strs[j - 1][i] != strs[j][i]) + { + break; + } + } + if(j < n) { break; } + } + return strs[0].substr(0, i); + } +}; +``` + +2、别人的程序 + +```C++ +class Solution +{ + public: + string longestCommonPrefix(vector &strs) + { + if(strs.empty()) return ""; + int right_most = strs[0].size() - 1; + for(size_t i = 1; i < strs.size(); i++) + for(int j = 0; j <= right_most; j++) + if(strs[i][j] != strs[0][j]) + right_most = j - 1; + return strs[0].substr(0, right_most + 1); + } +}; +``` + + + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/14/note_Yac836.md b/leetcode/14/note_Yac836.md new file mode 100644 index 0000000..762e7db --- /dev/null +++ b/leetcode/14/note_Yac836.md @@ -0,0 +1,60 @@ +## 链接 + + +https://leetcode.com/problems/longest-common-prefix/ + + + +## 补充描述 + +1. 以第一个字符串为基准开始比较,去第一个字符串中每个字符开始与后面的字符串中的字符开始比较 +2. 如果相同,则继续比较第二个,第三个,... 并且将每次相同结果进行累加 +3. 如果不同,则结束 +4. 返回累加结果 + + +## 代码 + + +```c++ +string longestCommonPrefix(vector& strs) { + if (strs.empty()) + return ""; + if (strs.size() == 1) + return strs[0]; + vector::size_type begin; + int index; + int len = strs[0].size(); + vector::size_type strsLen = strs.size(); + string res; + bool flag = true; + for (index = 0; index < len; index++) { + for (begin = 1;begin < strsLen; begin++) { + if (strs[0][index] != strs[begin][index]) { + flag = false; + break; + } + } + if (!flag) { + break; + } + else { + res = res + strs[0][index]; + } + } + return res; +} + + +``` + +## mzf评审 + +1. 缓存的东西有点多了,跑下来是多少ms? +2. flag没必要,看下我的提交,或者discuss + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/14/note_bajdcc.md b/leetcode/14/note_bajdcc.md new file mode 100644 index 0000000..c57994e --- /dev/null +++ b/leetcode/14/note_bajdcc.md @@ -0,0 +1,156 @@ +## 链接 + + +https://leetcode.com/problems/longest-common-prefix/ + + +## 题目 + +求给定字符串数组的最大公共前缀。 + + + +## 释义 + +### 常规解法 + +双重for循环,将strs看作二维数组,按列推进。 + +### 另类解法 + +脑洞出没:只能从左往右遍历?错了!还可以二分遍历~ + +该方法纯属娱乐,其实貌似大约也许可能并不能提高效率,摔!不过尝试一种新方法未尝不可? + +### 二分遍历法 + +来熟悉一下二分查找~ + +1. 设定下界lower和上界upper,设定中点mid=(lower+upper)/2 +2. 若中点值较大,则范围缩小为lower~mid-1 +3. 若中点值较小,则范围缩小为mid+1~upper +4. 若中点值相等,则查找成功 +5. 若lower>upper,则查找失败 + +那么这里的二分遍历是怎样呢? + +1. 设定下界lower和上界upper,设定中点mid=(lower+upper)/2 +2. 若中点值匹配,这时要看lower~mid-1部分;如果lower~mid-1全部匹配,则结果取决于mid+1~upper的值,否则结果取决于lower~mid-1的值 +3. 若中点值不匹配,这时只要看lower~mid-1部分 + + +### 多线程优化 + +真实情况中,我猜,strs应该是一个G级别的庞然大物。。 + +为了解决效率的问题,需要进行多线程优化。 + +常规解法:按最短长度len,假如我有4个线程,那么每个线程分配len/4长度的任务。 + +问题来了——很不幸,3个线程都做了无用功。。 + +- 线程1:i'm the first!!! oh, 2500000 strings are true! 蛤蛤蛤! +- 线程2:false on 1st, excuse me??? +- 线程3:false on 1st, r u crazy??? +- 线程4:false on 1st, what the %^&$??? +- CPU:r u kidding me??? remind me of lian-fa-ke... + +尴尬:当线程2-4集体罢工的时候,线程1还在嘿咻嘿咻地工作,杀人的心都有了。这里线程A不能打扰线程B工作。 + +这个尴尬的问题是无法解决的,要么您老分配任务的时候好好想想?? + +好吧,**减小任务粒度**,可以解决问题。 + +—————————— + +(二分解法) + +思路:先画一个lower-upper的饼,让某个线程去分饼。它从中间开始分,将饼分成两块(左边一块大的,右边一块小的),如果运气不好,两块还得继续分;运气好,只需要分前面一块,后面一块可以不要了。运气好的情况不讨论。运气不好的时候,问题来了,右边一块匹配!然而左边一块失败!处理右边一块的线程:excuse me???不过、、、右边一块饼并不是由单独一个线程去分的(递归嘛),也就是说,如果任务失败,那么相当于所有线程都白白干了一件蠢事;当然了,如果任务顺利,线程们都会欢欣鼓舞。 + +所以二分法有一个人情味的好处:**同甘共苦**,仿佛线程们有了生命一样。每个线程都知道自己的任务范围在变得越来越小,这样就能看到希望! + +从快速定界方面看,常规解法是一次性出上界,而二分解法可以渐渐缩小上界范围。 + +从多线程方面看,二分法粒度是1,常规法可以>=1。 + +总结,二分法比常规法多做了一件事件:**探测上界范围**,**适用于快速估算**。为什么写二分法,因为闲。。 + +—————————— + +假如要做个进度条,用常规解法,从左到右读条,不知道什么时候突然就满了,等待时间去问薛定谔的猫吧;用二分解法,参考xp的磁盘碎片整理,可以在没有遍历结束前缩小范围。 + +## 补充描述 + +运行时间看人品系列:https://leetcode.com/submissions/detail/87863222/ + + + + +## 代码 + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +#include +#include + +using namespace std; + +class Solution { +public: + string longestCommonPrefix(vector &strs) { + if (strs.empty()) + return ""; + if (strs.size() == 1) + return strs[0]; + long min_len = -1; + int min_idx = -1; + int i = 0; + for (auto &s : strs) { + if (s.length() < min_len) { + min_len = s.length(); + min_idx = i; + } + i++; + } + if (min_len == 0) + return ""; + auto min_str = strs[min_idx]; + return min_str.substr(0, 1 + getMax(strs, min_str, 0, min_len - 1)); + } + + long getMax(const vector &vec, const string &str, long lower, long upper) { + if (lower == upper) + return can(vec, str[lower], lower) ? lower : -1; + auto mid = (lower + upper) / 2; + if (!can(vec, str[mid], mid)) { + return lower == mid ? -1 : getMax(vec, str, lower, mid - 1); + } + if (lower == mid) { + auto up = getMax(vec, str, mid + 1, upper); + return mid == upper ? upper : (up == -1 ? mid : up); + } + auto lo = getMax(vec, str, lower, mid - 1); + if (lo == mid - 1) { + auto up = getMax(vec, str, mid + 1, upper); + return mid == upper ? upper : (up == -1 ? mid : up); + } + return lo; + } + + bool can(const vector &vec, const char &ch, long idx) { + for (auto &s : vec) { + if (s[idx] != ch) + return false; + } + return true; + } +}; +``` + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/14/note_leakey.md b/leetcode/14/note_leakey.md new file mode 100644 index 0000000..bdfb712 --- /dev/null +++ b/leetcode/14/note_leakey.md @@ -0,0 +1,64 @@ +## 链接 + + +https://leetcode.com/problems/longest-common-prefix/ + + +## 题目 + + + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { +public: + string longestCommonPrefix(vector& strs) { + if (strs.size() == 0) return string(); + int i, j; + for (i = 0; i < strs[0].length(); i++) + for (j = 1; j < strs.size(); j++) + if (strs[j][i] != strs[0][i]) + return strs[0].substr(0, i); + return strs[0].substr(0, i); + } +}; + + +``` + +## mzf评审 + +1. 直接上代码?差评。下次再写成这样就没有奖品拿了,哈哈。 +2. `if (strs.empty()) return "";` +3. 我还是建议把花括号都加上 +4. `i++' 改成`++i` + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/14/note_mzf.md b/leetcode/14/note_mzf.md new file mode 100644 index 0000000..229eec2 --- /dev/null +++ b/leetcode/14/note_mzf.md @@ -0,0 +1,179 @@ +## + +[https://leetcode.com/problems/longest-common-prefix/](https://leetcode.com/problems/longest-common-prefix/) + +## Ŀ + +ĿҪһstringУַеǰ׺ + + ["aa", "ab"], ô"a" + +## + +N.A. + +## + +ʼд֮ǰһЩ + +### ϳ + +``` +["aa"]-->"" +[]-->"" +``` + +### + +``` +["aa", "ab"]-->"a" +["aaa", "aab"]-->"aa" +["aa", "bb"]-->"" +``` + +## + +Ƚ뵽DZһstringеַȷϺstringǷҲЩַ + +```c++ +string longestCommonPrefix(vector& strs) +{ + if( !strs.size() ) + { + return ""; + } + + if( strs.size() ==1 ) + { + return strs.at(0); + } + + string sFirst = strs.at(0); + + for( int i = 0; i < sFirst.size(); ++i) + { + for( int j = 1; j < strs.size(); ++j ) + { + string sTemp = strs.at(j); + if( sTemp.size() <= i || sTemp[i] != sFirst[i] ) + { + return i == 0 ? "" : sFirst.substr(0, i); + } + } + + } + + return sFirst; +} +``` + +֮13ms鿴ϸڻִᷢ󲿷˵Ľʱ䶼10msڡ + +ҪٿһʡЩʱ + +`size()`˶Σһ? **æбҪ** + +ѭڲȡ`strs.at(j)`ûҪģ˳±dzġ + +ͬģsFirstҲ + +```c++ +string longestCommonPrefix(vector& strs) +{ + auto vecSize = strs.size(); + + if( !vecSize ) + { + return ""; + } + + if( vecSize ==1 ) + { + return strs.at(0); + } + + + for( int i = 0; i < strs.at(0).size(); ++i) + { + for( int j = 1; j < vecSize; ++j ) + { + if( strs.at(j).size() <= i || strs.at(j)[i] != strs.at(0)[i] ) + { + return i == 0 ? "" : strs.at(0).substr(0, i); + } + } + + } + + return strs.at(0); +} + +``` + +6msֻܻ17.75%Ϊ˶6ms + +Լ벻Żˣ͸Ʊ𰸶Աһ + +[https://discuss.leetcode.com/topic/20991/accepted-c-6-lines-4ms/2](https://discuss.leetcode.com/topic/20991/accepted-c-6-lines-4ms/2) + +ҪһӦsubstrϣҲķʽ + +``` +string longestCommonPrefix(vector& strs) { + auto vecSize = strs.size(); + + if( !vecSize ) + { + return ""; + } + + string sPrefix = ""; + for( int i = 0; i < strs.at(0).size(); ++i) + { + for( int j = 1; j < vecSize; ++j ) + { + if( strs.at(j).size() <= i || strs.at(j)[i] != strs.at(0)[i] ) + { + return sPrefix; + } + } + sPrefix += strs.at(0)[i]; + } + + return strs.at(0); +} +``` + +6msٸĵĻɶԾͱˡ + +Ȼ޷ġɡ + +## + +ѧ`string.find` + +```c++ +string longestCommonPrefix(vector& strs) { + auto vecSize = strs.size(); + + if( !vecSize ) + { + return ""; + } + + string sPrefix = ""; + for( int i = 0; i < strs.at(0).size(); ++i) + { + sPrefix += strs.at(0)[i]; + for( int j = 1; j < vecSize; ++j ) + { + if( strs.at(j).find(sPrefix) != 0 ) + { + return sPrefix.erase(i,1); + } + } + } + + return strs.at(0); +} +``` diff --git a/leetcode/15/note.md b/leetcode/15/note.md new file mode 100644 index 0000000..3dfc32e --- /dev/null +++ b/leetcode/15/note.md @@ -0,0 +1,59 @@ +## 链接 + +【中等难度】15. 3Sum + +https://leetcode.com/problems/3sum/ + + +## 题目 + +Given an array *S* of *n* integers, are there elements *a*, *b*, *c* in *S* such that *a* + *b* + *c* = 0? Find all unique triplets in the array which gives the sum of zero. + +**Note:** The solution set must not contain duplicate triplets. + +``` +For example, given array S = [-1, 0, 1, 2, -1, -4], + +A solution set is: +[ + [-1, 0, 1], + [-1, -1, 2] +] +``` + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/15/note_Josan.md b/leetcode/15/note_Josan.md new file mode 100644 index 0000000..2f70cb0 --- /dev/null +++ b/leetcode/15/note_Josan.md @@ -0,0 +1,128 @@ +## 链接 + +【中等难度】15. 3Sum + +https://leetcode.com/problems/3sum/ + + +## 题目 + +Given an array *S* of *n* integers, are there elements *a*, *b*, *c* in *S* such that *a* + *b* + *c* = 0? Find all unique triplets in the array which gives the sum of zero. + +**Note:** The solution set must not contain duplicate triplets. + +``` +For example, given array S = [-1, 0, 1, 2, -1, -4], + +A solution set is: +[ + [-1, 0, 1], + [-1, -1, 2] +] +``` + +## 释义 + +给定一个数组,找出所有的3元组,这些3元组之和为0,并且没有重复的元组。而且按顺序输出 + +## 补充描述 + +一开始打算用两个指针技术,进行求解。但是遇到“下一步怎么走“问题。 +最后用了一个重复查询的方法,进行搜索。 + + + + + +## 代码 + + + + + + +```c++ + + +vector> threeSum(vector& nums) +{ + bool myComp(vector & a, vector & b); + sort(nums.begin(), nums.end()); + vector temp(3); + vector> res; + res.reserve(100); + auto size = nums.size(); + if(size >= 3) + { + decltype(size) st = 0; + decltype(size) ed = size - 1; + while((ed - st) >= 1 && nums[st] <= 0 && nums[ed] >= 0) + { + while((ed - st) >= 1 && nums[ed] >= 0) + { + int wt = -(nums[st] + nums[ed]); + auto mid = find(nums.begin() + st + 1, nums.begin() + ed, wt); + if(mid != nums.begin() + ed) + { + temp[0] = nums[st]; + temp[1] = *mid; + temp[2] = nums[ed]; + res.push_back(temp); + } +                //寻找下一个不重复的数值num[ed] +                while((ed - st) >= 1 && nums[ed] == nums[ed - 1]) + { + --ed; + } + --ed; + } +            //寻找下一个不重复的数值num[st] +            while((ed - st) >= 1 && nums[st] == nums[st + 1]) + { + ++st; + } + ++st; +            //更新ed +            ed = size - 1; + } + } + return res; +} + + + +``` + +别人比较好的程序,很简短。使用的是Two-pointer Tech + +```c++ +vector> threeSum(vector& nums) +{ + vector> triples; + triples.reserve(200); + sort(nums.begin(), nums.end()); + int i = 0, last = nums.size() - 1; + while(i < last) + { + int a = nums[i], j = i + 1, k = last; + while(j < k) + { + int b = nums[j], c = nums[k], sum = a + b + c; + if(sum == 0) triples.push_back({ a, b, c }); + if(sum <= 0) while(nums[j] == b && j < k) j++; + if(sum >= 0) while(nums[k] == c && j < k) k--; + } + while(nums[i] == a && i < last) i++; + } + return triples; +} + + +``` + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/15/note_leakey.md b/leetcode/15/note_leakey.md new file mode 100644 index 0000000..309cdf2 --- /dev/null +++ b/leetcode/15/note_leakey.md @@ -0,0 +1,97 @@ +## 链接 + +【中等难度】15. 3Sum + +https://leetcode.com/problems/3sum/ + + +## 题目 + +Given an array *S* of *n* integers, are there elements *a*, *b*, *c* in *S* such that *a* + *b* + *c* = 0? Find all unique triplets in the array which gives the sum of zero. + +**Note:** The solution set must not contain duplicate triplets. + +``` +For example, given array S = [-1, 0, 1, 2, -1, -4], + +A solution set is: +[ + [-1, 0, 1], + [-1, -1, 2] +] +``` + +## 释义 + + + + + + +## 补充描述 +Simple python solution: +```python +class Solution(object): + def threeSum(self, nums): + """ + :type nums: List[int] + :rtype: List[List[int]] + """ + nums.sort() + C, maxi = set(), len(nums) - 2 # maxi: max index of pointer i backward + for i in xrange(maxi): + for j in xrange(i + 1, maxi + 1): + if -nums[i] - nums[j] in nums[j + 1: ]: + C.add((nums[i], nums[j], -nums[i] - nums[j])) + return list(C) +``` + + + + + +## 代码 + + + + + + +```c++ +class Solution { +public: + vector> threeSum(vector& nums) { + sort(nums.begin(), nums.end()); + vector> idx; + int numsLen = nums.size(); + for (int pl = 0; pl < numsLen; pl++){ + if (pl > 0 && nums[pl] == nums[pl - 1]) + continue; // jump duplicate number from left + int pm = pl + 1, pr = numsLen - 1; + while (pm < pr){ + int sum = nums[pl] + nums[pm] + nums[pr]; + if (sum > 0) + pr--; // get a smaller number + else if (sum < 0) + pm++; // get a bigger number + else{ + idx.push_back(vector {nums[pl], nums[pm], nums[pr]}); + while (pm + 1 < pr && nums[pm] == nums[pm + 1]) pm++; // pass dup + while (pr - 1 < pm && nums[pr] == nums[pr - 1]) pr--; + pm++; + pr--; + } + } + } + return idx; + } +}; +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/19/note_Josan019.md b/leetcode/19/note_Josan019.md new file mode 100644 index 0000000..736199b --- /dev/null +++ b/leetcode/19/note_Josan019.md @@ -0,0 +1,77 @@ +## 链接 + + +https://leetcode.com/problems/remove-nth-node-from-end-of-list/ + + +## 解题思路 + +1. 先遍历一个pre,作为侦探兵。 +2. 一次遍历,只要pre为NULL,就可以找出要删除的元素的前一个位置,即为res。 +3. 删除元素 + +***注意*** + +要删除元素为第一个位置时,返回值问题。 + + + +## 代码 + + + +```c++ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(NULL) {} + * }; + */ +class Solution +{ + public: + ListNode* removeNthFromEnd(ListNode* head, int n) + { + if (n < 0||head==NULL||head->next==NULL) return NULL; + + //pre表示从head开始遍历第n个结点,意思就是pre在res之前n+1个结点 + //那么当pre指向NULL时,res正好是倒数第n个结点的前置结点。 + ListNode* pre = head; + while (n&&pre) + { + pre = pre->next; + --n; + } + + //n!=0表示n的大于链表的长度,报错 + if(n!=0) return NULL; + + //flag用来标识是否删除的是头指针,如果是,则为true + bool flag = (n == 0 && pre == NULL); + ListNode* dumpHead = new ListNode(0); + dumpHead->next = head; + ListNode* res = dumpHead; + while (pre) + { + pre = pre->next; + res = res->next; + } + //删除 + res->next = res->next->next; + if (flag) head = res->next; + delete dumpHead; + return head; + } +}; + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/19/note_Yac836.md b/leetcode/19/note_Yac836.md new file mode 100644 index 0000000..8f20898 --- /dev/null +++ b/leetcode/19/note_Yac836.md @@ -0,0 +1,57 @@ +## 链接 + + +https://leetcode.com/problems/remove-nth-node-from-end-of-list/ + + +## 解题思路 + +1. 遍历求出链表长度 +2. 找出要删除的元素的前一个位置 +3. 删除元素 + +***注意*** + +1. 要删除元素为第一个位置时,返回值问题。 + + + + + + +## 代码 + + + + + + +```c++ +ListNode* removeNthFromEnd(ListNode* head, int n) { + ListNode *begin = head; + int len = 1; + while (begin->next != nullptr) { + len++; + begin = begin->next; + } + if (len == n) + return head->next; + int remove = len - n; + begin = head; + len = 1; + while (len < remove) { + begin = begin->next; + len++; + } + begin->next = begin->next->next; + return head; +} +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/19/note_leakey.md b/leetcode/19/note_leakey.md new file mode 100644 index 0000000..71d9264 --- /dev/null +++ b/leetcode/19/note_leakey.md @@ -0,0 +1,63 @@ +## 链接 + + +https://leetcode.com/problems/remove-nth-node-from-end-of-list/ + + +## 题目 + + + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { +public: + ListNode* removeNthFromEnd(ListNode* head, int n) { + ListNode *fp = head, *sp = head; //use two pointers + for (int i = 0; i < n; i++) + fp = fp -> next; + if (fp == NULL) + return head -> next; + while (fp -> next != NULL){ + fp = fp -> next; + sp = sp -> next; + } + sp -> next = sp -> next -> next; + return head; + } +}; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/20/node_Wanghonglu.md b/leetcode/20/node_Wanghonglu.md new file mode 100644 index 0000000..180008e --- /dev/null +++ b/leetcode/20/node_Wanghonglu.md @@ -0,0 +1,114 @@ +```c++ +class Solution { +public: + bool isValid(string s) { + char elem=0,left_elem=0,right_elem=0; + Stack *ptr = new Stack( (int)s.length() ); + for( int i=0;iPushStack(elem); + break; + case ']': + case ')': + case '}': + { + ptr->GetTopStack(left_elem); + switch( left_elem ) + { + case '[': + right_elem = ']'; + break; + case '(': + right_elem = ')'; + break; + case '{': + right_elem = '}'; + break; + } + if( right_elem == elem ) + { + ptr->PopStack(); + break; + } + else + { + delete ptr; + return false; + } + } + default: + { + delete ptr; + return false; + } + + } + } + if(ptr->IsEmptyStack()) + { + delete ptr; + return true; + } + delete ptr; + return false; + } +class Stack{ +public: + Stack( int size ) + { + m_size = size; + m_ptr = new char[size]; + memset( m_ptr, 0x00, size ); + m_top = 0; + } + ~Stack() + { + delete []m_ptr; + m_top = 0; + m_size = 0; + } + bool IsFullStack() + { + return m_size == m_top; + } + bool IsEmptyStack() + { + return m_top ==0; + } + bool PushStack( char elem ) + { + if( IsFullStack() ) + return false; + m_ptr[m_top] = elem; + m_top++; + return true; + } + bool PopStack( ) + { + if( IsEmptyStack()) + return false; + m_top--; + return true; + } + bool GetTopStack( char& elem ) + { + if( IsEmptyStack() ) + return false; + elem = m_ptr[m_top-1]; + return true; + } +private: + char* m_ptr; + int m_top; + int m_size; +}; + + +}; +``` diff --git a/leetcode/20/note_Josan020.md b/leetcode/20/note_Josan020.md new file mode 100644 index 0000000..b3445c7 --- /dev/null +++ b/leetcode/20/note_Josan020.md @@ -0,0 +1,118 @@ +## 链接 + + +https://leetcode.com/problems/valid-parentheses/ + +## 解题思路 + +典型的stack的符号配对问题。 + +注意一些特殊的测试用例就好 +()( ) ()() [ + + +## 代码 + +```c++ +class Solution { +public: + bool isValid(string s) { + if(s.size( ) == 0) + { + return false; + } + stack st; + int i = 0; + //加入@主要是为了当stack为空时,以防出现取st.top()的报错 + //相应测试用例,eg: ) + st.push('@'); + while(!st.empty( )&&i!=s.size()){ + switch(s[i]){ + case '(': + case '[': + case '{': + st.push(s[i++]); + break; + case ')': + if(st.top( ) != '('){ + return false; + } + else{ + st.pop( ); + ++i; + } + break; + case ']': + if(st.top( ) != '['){ + return false; + } + else{ + st.pop( ); + ++i; + } + break; + case '}': + if(st.top( ) != '{'){ + return false; + } + else{ + st.pop( ); + ++i; + } + break; + //出现其他无效字符 + default: return false; + } + } + return (st.size( ) == 1) ? true : false; + } +}; +``` + +上面的程序比较繁琐,而且对case ]})的案例无法进行统一 + +可以参考这个改进版 +```c++ +class Solution { +public: + bool isValid(string s){ + //suppose null string is illegal + if(s.size( ) == 0){ + return false; + } + stack st; + map cm{ {')','(' },{']','[' },{'}','{' } }; + for(int i = 0; i != s.size( ); ++i){ + switch(s[i]){ + case '(': + case '[': + case '{': + st.push(s[i]); + break; + case ')': + case ']': + case '}': + if(st.empty( ) || st.top( ) != cm[s[i]]){ + return false; + } + else{ + st.pop( ); + break; + } + //if illegal character appears, like @ # $ % a ... , return false + default: + return false; + } + } + return st.empty( ); + } +}; +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/20/note_Yac836.md b/leetcode/20/note_Yac836.md new file mode 100644 index 0000000..182c4eb --- /dev/null +++ b/leetcode/20/note_Yac836.md @@ -0,0 +1,73 @@ +## 链接 + + +https://leetcode.com/problems/valid-parentheses/ + +## 解题思路 + +1. 利用stack +2. 如果栈顶元素和字符串中下一个元素相等,则栈顶元素出栈,如果不能,则下一个元素入栈。 + + + + +## 代码 + + + + + + +```c++ +bool isValid(string s) { + if (s.empty()) + return true; + auto len = s.size(); + string::size_type index; + stack cs; + cs.push(s[0]); + for (index = 1; index < len; index++) { + if (cs.empty()) + if (s[index] != ')'&&s[index] != '}'&&s[index] != ']') { + cs.push(s[index]); + continue; + } + else { + return false; + } + char e = cs.top(); + if (e == '(') { + if (s[index] == ')') + cs.pop(); + else + cs.push(s[index]); + } + else if (e == '{') { + if (s[index] == '}') + cs.pop(); + else + cs.push(s[index]); + } + else if (e == '[') { + if (s[index] == ']') + cs.pop(); + else + cs.push(s[index]); + } + } + if (cs.empty()) + return true; + else + return false; +} + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/20/note_leakey.md b/leetcode/20/note_leakey.md new file mode 100644 index 0000000..1be6bc0 --- /dev/null +++ b/leetcode/20/note_leakey.md @@ -0,0 +1,56 @@ +## 链接 + + +https://leetcode.com/problems/valid-parentheses/ + + +## 题目 + + + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { +public: + bool isValid(string s) { + stack p; + for (char& c : s) + p.empty() ? p.push(c) : (c == p.top() + 2 || c == p.top() + 1 ? p.pop() : p.push(c)); + return p.empty(); + } +}; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git "a/leetcode/20/\350\257\264\346\230\216.md" "b/leetcode/20/\350\257\264\346\230\216.md" new file mode 100644 index 0000000..692da96 --- /dev/null +++ "b/leetcode/20/\350\257\264\346\230\216.md" @@ -0,0 +1,48 @@ +### 具体的GitHub操作如下 + +#### 1. Fork + +https://github.com/githubwoniu/learnprogram + +#### 2. 创建一个新文件 + +1. 进入自己的仓库 +2. 进入目录learnprogram/leetcode/09/ +3. 点击Create New File +4. 文件名可以是`note_用户名.md`的形式,如`note_githubwoniu.md` + +#### 3. 添加解题笔记 + +这次要解的题目是 + +[leetcode 20](https://leetcode.com/problems/valid-parentheses/#/description) + +笔记格式参考 + +[答题格式](https://github.com/githubwoniu/learnprogram/blob/master/%E7%AD%94%E9%A2%98%E6%A0%BC%E5%BC%8F_%E4%B8%8D%E8%A6%81%E4%BF%AE%E6%94%B9%E6%AD%A4%E6%96%87%E4%BB%B6.md) + +**不要修改此文件** + +#### 4. Commit + +#### 5. Pull Request + +# 更多github操作指南 + +请查看,仓库首页的文章 + +https://github.com/githubwoniu/learnprogram + +# 注意 + +公众号随机选取本仓库的提交供大家吐糟,以便相互学习提高。 + +凡提交到本仓库的文章即认为授权公众号使用 + +# 关注公众号 + +一起学习吧~ + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +由于微信群二维码只有七天有效期,这里就不放了,请到公众号底部菜单栏查找。 diff --git a/leetcode/21/note_Josan021.md b/leetcode/21/note_Josan021.md new file mode 100644 index 0000000..32f037e --- /dev/null +++ b/leetcode/21/note_Josan021.md @@ -0,0 +1,85 @@ +## 链接 + + +https://leetcode.com/problems/merge-two-sorted-lists/ + + +## 解题思路 + +先建立一个头指针,然后依次按顺序插入这个头指针的后面。 + + + +## 代码 + +```c++ +/** +* Definition for singly-linked list. +* struct ListNode { +* int val; +* ListNode *next; +* ListNode(int x) : val(x), next(NULL) {} +* }; +*/ +class Solution +{ + public: + ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) + { + if (l1 == NULL) + { + return l2; + } + if (l2 == NULL) + { + return l1; + } + ListNode head(0); + ListNode* res = &head; + ListNode* p = res; + + while (l1&&l2) + { + if (l1->val < l2->val) + { + p->next = l1; + l1 = l1->next; + } + else + { + p->next = l2; + l2 = l2->next; + } + p = p->next; + } + p->next = l1 ? l1 : l2; + return res->next; + } +}; +``` +网上看到一个比较有意思的解法, +递归版 +```c++ +class Solution { +public: + ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { + if(l1 == NULL) return l2; + if(l2 == NULL) return l1; + + if(l1->val < l2->val) { + l1->next = mergeTwoLists(l1->next, l2); + return l1; + } else { + l2->next = mergeTwoLists(l2->next, l1); + return l2; + } + } +}; +``` + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/21/note_Yac836.md b/leetcode/21/note_Yac836.md new file mode 100644 index 0000000..82bf960 --- /dev/null +++ b/leetcode/21/note_Yac836.md @@ -0,0 +1,68 @@ +## 链接 + + +https://leetcode.com/problems/merge-two-sorted-lists/ + + +## 解题思路 + +1. 先新建一个节点tres,指向两个链表中最小的。 +2. 再新建一个节点res,使它指向tres,用于保存结果。 +3. 然后一次比较两个链表中的元素,使tres指向其中较小元素,然后后移tres,使它指向它的下一个 + + + + +## 代码 + + + + + + +```c++ +ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { + if (!l1 && !l2) + return nullptr; + if (!l1) + return l2; + if (!l2) + return l1; + ListNode* tres; + if (l1->val < l2->val) { + tres = l1; + l1 = l1->next; + } + else { + tres = l2; + l2 = l2->next; + } + ListNode* res = tres; + while (l1&&l2) { + if (l1->val < l2->val) { + tres->next = l1; + l1 = l1->next; + } + else { + tres->next = l2; + l2 = l2->next; + } + tres = tres->next; + } + if (l1) + tres->next = l1; + if (l2) + tres->next = l2; + return res; +} + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/21/note_leakey.md b/leetcode/21/note_leakey.md new file mode 100644 index 0000000..a3617b0 --- /dev/null +++ b/leetcode/21/note_leakey.md @@ -0,0 +1,86 @@ +## 链接 + + +https://leetcode.com/problems/merge-two-sorted-lists/ + + +## 题目 + + + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { +public: + ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { + ListNode *p1 = l1, *p2 = l2, *p, *head; + if (p1 == NULL) + return l2; + else if (p2 == NULL) + return l1; + if (p1 -> val <= p2 -> val){ + head = p1; + p1 = p1 -> next; + }// first node same with smaller one + else{ + head = p2; + p2 = p2 -> next; + } + p = head; + while (p1 != NULL || p2 != NULL){ + if (p1 == NULL){ + p -> next = p2; + p2 = p2 -> next; + } // if l1 ends + else if (p2 == NULL){ + p -> next = p1; + p1 = p1 -> next; + } + else if (p1 -> val <= p2 -> val){ + p -> next = p1; + p1 = p1 -> next; + } + else{ + p -> next = p2; + p2 = p2 -> next; + } + p = p -> next; // p move to the next node + } + return head; + } +}; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/22/note.md b/leetcode/22/note.md new file mode 100644 index 0000000..d743f43 --- /dev/null +++ b/leetcode/22/note.md @@ -0,0 +1,61 @@ +## 链接 + +【中等难度】22. Generate Parentheses(生成括号) + +https://leetcode.com/problems/generate-parentheses/ + + +## 题目 + +Given *n* pairs of parentheses, write a function to generate all combinations of well-formed parentheses. + +For example, given *n* = 3, a solution set is: + +``` +[ + "((()))", + "(()())", + "(())()", + "()(())", + "()()()" +] +``` + +*Tags: Backtracking* + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/22/note_Josan022.md b/leetcode/22/note_Josan022.md new file mode 100644 index 0000000..d3cd97c --- /dev/null +++ b/leetcode/22/note_Josan022.md @@ -0,0 +1,80 @@ +## 链接 + +【中等难度】22. Generate Parentheses(生成括号) + +https://leetcode.com/problems/generate-parentheses/ + + +## 题目 + +Given *n* pairs of parentheses, write a function to generate all combinations of well-formed parentheses. + +For example, given *n* = 3, a solution set is: + +``` +[ + "((()))", + "(()())", + "(())()", + "()(())", + "()()()" +] +``` + +*Tags: Backtracking* + +## 释义 + +遇到中等难度的题目,就要像很久。这题还是看着答案,码了一遍。 + +应该是回溯的方法。Backtraking + +## 代码 + +```c++ +class Solution +{ + private: + //lhs表示path里面左括号个数,rhs表示path里面左括号个数 + //res用来记录返回结果,path记录当前字符串; + void generate(int n, int lhs, int rhs, vector& res, string& path) + { + //lhs达到最大值,那么只能继续加入右括号 + if(n == lhs) + { + string s(path); + res.push_back(s.append(n - rhs, ')')); + return; + } + path.push_back('('); + generate(n, lhs + 1, rhs, res, path); + path.pop_back(); + + //左括号个数大于右括号个数,才可以插入) + if(lhs > rhs) + { + path.push_back(')'); + generate(n, lhs, rhs + 1, res, path); + path.pop_back(); + } + } + + public: + vector generateParenthesis(int n) + { + vector res; + string path; + if(n > 0) generate(n, 0, 0, res, path); + return res; + } +}; + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/22/note_leakey.md b/leetcode/22/note_leakey.md new file mode 100644 index 0000000..2f4863d --- /dev/null +++ b/leetcode/22/note_leakey.md @@ -0,0 +1,125 @@ +## 链接 + +【中等难度】22. Generate Parentheses(生成括号) + +https://leetcode.com/problems/generate-parentheses/ + + +## 题目 + +Given *n* pairs of parentheses, write a function to generate all combinations of well-formed parentheses. + +For example, given *n* = 3, a solution set is: + +``` +[ + "((()))", + "(()())", + "(())()", + "()(())", + "()()()" +] +``` + +*Tags: Backtracking* + +## 释义 + + + + + + +## 补充描述 +A python solution: +```python +class Solution(object): + def generateParenthesis(self, n): + """ + :type n: int + :rtype: List[str] + """ + B = [i for i in xrange(n)] + p = "" + for k in xrange(0, 2 * n): + p += "(" if k in B else ")" + A = [p] + j = i = n - 1 + while True: + if B[j] != 2 * j: # adjustment b + B[j] += 1 + else: + while j != 0: + j -= 1 + if B[j] != 2 * j: + B[j] += 1 + for m in xrange(j + 1, n): + B[m] = B[m - 1] + 1 + j = n - 1 + break + if j <= 0: + return A + p = "" + for k in xrange(0, 2 * n): + p += "(" if k in B else ")" + A.append(p) + +``` + + + + + +## 代码 + + + + + + +```c++ + +class Solution { +public: + vector generateParenthesis(int n) { + vector parenTable; + if (n == 0) + return parenTable; + string s; + int pl = n, pr = n; + for (int i = 0; i < n; i++) s += "("; + for (int i = 0; i < n; i++) s += ")"; //s = "(((...()...)))" + while (s != ""){ + parenTable.push_back(s); + while (s != "" && (s.back() == ')' || pl - 1 < pr + 1)){ + s.back() == ')' ? pr-- : pl --; + s.pop_back(); + } + if (s != ""){ + s.back() = ')'; + pl--, pr++; + while (pl < n){ + s += '('; + pl++; + } + while (pr < n){ + s += ')'; + pr++; + } + } + } + return parenTable; + } +}; + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/24/note_Josan024.md b/leetcode/24/note_Josan024.md new file mode 100644 index 0000000..f0c6f41 --- /dev/null +++ b/leetcode/24/note_Josan024.md @@ -0,0 +1,70 @@ +## 链接 + + +https://leetcode.com/problems/swap-nodes-in-pairs/ + + +## 解题思路 + +首先,建了一个虚假头,这样可以统一操作。 +建立两个指针pre,p;pre指向p的前面一个结点。 +然后每两个指针,进行一次操作。 + +注意:结点个数为奇数的特例。 + + + + +## 代码 + + +```c++ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(NULL) {} + * }; + */ +class Solution +{ + public: + ListNode* swapPairs(ListNode* head) + { + ListNode* dumpHead = new ListNode(100); + dumpHead->next = head; + + ListNode* p = head; + ListNode* pre = dumpHead; + + while(p) + { + //处理奇数结点的情况 + if(p->next == NULL) + { + ListNode* tem = dumpHead->next; + delete dumpHead; + return tem; + } + pre->next = p->next; + p->next = p->next->next; + pre->next->next = p; + pre = p; + p = p->next; + } + + ListNode* tem = dumpHead->next; + delete dumpHead; + return tem; + } +}; +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/24/note_Yac836.md b/leetcode/24/note_Yac836.md new file mode 100644 index 0000000..64794b4 --- /dev/null +++ b/leetcode/24/note_Yac836.md @@ -0,0 +1,49 @@ +## 链接 + + +https://leetcode.com/problems/swap-nodes-in-pairs/ + + +## 解题思路 + +1. 找到要交换的前驱就行。 + + + + +## 代码 + + + + + + +```c++ +//借鉴别人的代码 +ListNode* swapPairs(ListNode* head) { + if (!head || !head->next) return head; + ListNode tempNode(0); + ListNode *helper = &tempNode; + ListNode *ret = head; + ListNode *cur = helper; + while (ret && ret->next) { + ListNode *next = ret->next->next; + cur->next = ret->next; + cur = cur->next; + cur->next = ret; + cur = cur->next; + cur->next = nullptr; + ret = next; + } + if (ret) cur->next = ret; + return helper->next; +} +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/24/note_leakey.md b/leetcode/24/note_leakey.md new file mode 100644 index 0000000..cf96fa9 --- /dev/null +++ b/leetcode/24/note_leakey.md @@ -0,0 +1,75 @@ +## 链接 + + +https://leetcode.com/problems/swap-nodes-in-pairs/ + + +## 题目 + + + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { +public: + ListNode* swapPairs(ListNode* head) { + if (head == NULL || head -> next == NULL) + return head; + ListNode *p1 = head, *p2 = head, *p3 = head -> next, *p4 = head -> next -> next; + p2 -> next = p4; + p3 -> next = p2; + p1 = p3; + head = p1; //change first two nodes + while (p2 != NULL && p3 != NULL && p4 != NULL){ + if (p3 -> next -> next -> next != NULL){ + p1 = p1 -> next; + p2 = p2 -> next; + p3 = p3 -> next -> next -> next; + p4 = p4 -> next -> next; + p1 -> next = NULL; + p2 -> next = p4; + p3 -> next = p2; + p1 -> next = p3; + p1 = p1 -> next; + } + else + break; + } + return head; + } +}; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/26/note_Josan026.md b/leetcode/26/note_Josan026.md new file mode 100644 index 0000000..835023b --- /dev/null +++ b/leetcode/26/note_Josan026.md @@ -0,0 +1,86 @@ +## 链接 + +https://leetcode.com/problems/remove-duplicates-from-sorted-array/ + +##解题思路 + +去掉重复的数字,其实就是erase()函数的内部实现。 + +我采用的pre-check技巧。 + +不过,这题还有更精简的做法。 + + + +## 代码 + + + + + + +```c++ +class Solution +{ + public: + int removeDuplicates(vector& nums) + { + int res = 0; + for(int i = 0; i != nums.size();++i) + { + while((i+1)!=nums.size()&&nums[i+1] == nums[i]) + { + ++i; + } + nums[res++] = nums[i]; + } + return res; + } +}; + +``` + +与我的代码进行比较,感觉下面的代码更简洁一点 +```c++ +class Solution +{ + public: + int removeDuplicates(vector& nums) + { + //必须提前判断nums.empty() + if(nums.empty()) { return 0; } + + int index = 0; + for(int i = 1; i < nums.size(); ++i) + { + if(nums[index] != nums[i]) + { + nums[++index] = nums[i]; + } + } + return index + 1; + } +}; +``` + + +作弊法 +```c++ +class Solution +{ + public: + int removeDuplicates(vector& nums) + { + return distance(nums.begin(),unique(nums.begin(), nums.end())); + } +}; +``` + + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/26/note_Yac836.md b/leetcode/26/note_Yac836.md new file mode 100644 index 0000000..bf00bb4 --- /dev/null +++ b/leetcode/26/note_Yac836.md @@ -0,0 +1,49 @@ +## 链接 + + +https://leetcode.com/problems/remove-duplicates-from-sorted-array/ + +##解题思路 + +1. 定义两个迭代器`s1`,`s2`,` s1`用来记录不重复元素的位置,s2用寻找不重复的元素。 +2. 当`s2` 发现了不是重复的元素的时候,就将`s2`所指的元素插入到`s1`下一个所指的位置。 +3. 最后删除`s1`到数组结束的元素 + + +## 代码 + + + + + + +```c++ +int removeDuplicates(vector& nums) { + if (nums.size() == 0) + return 0; + vector::size_type len = nums.size(); + vector::iterator s1 = nums.begin(); + vector::iterator s2 = nums.begin() + 1; + vector::iterator e = nums.end(); + while (s2 != e) { + if (*s1 == *s2) + s2++; + else { + s1++; + *s1 = *s2; + s2++; + } + } + nums.erase(s1 + 1, e); + return nums.size(); +} + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/26/note_leakey.md b/leetcode/26/note_leakey.md new file mode 100644 index 0000000..349dda5 --- /dev/null +++ b/leetcode/26/note_leakey.md @@ -0,0 +1,57 @@ +## 链接 + + +https://leetcode.com/problems/remove-duplicates-from-sorted-array/ + + +## 题目 + + + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { +public: + int removeDuplicates(vector& nums) { + int i = 0, n = nums.size(); + for (int j = 1; j < n; j++) + if (nums[i] != nums[j]) + nums[++i] = nums[j]; + return n <= 1 ? n : i + 1; + } +}; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/27/note_Josan027.md b/leetcode/27/note_Josan027.md new file mode 100644 index 0000000..567e566 --- /dev/null +++ b/leetcode/27/note_Josan027.md @@ -0,0 +1,40 @@ +## 链接 + + +https://leetcode.com/problems/remove-element/ + + +## 解题思路 + +非常简单的一个题目。删除数组中指定的值。 + + +## 代码 + + +```c++ +class Solution +{ + public: + int removeElement(vector& nums, int val) + { + int index = 0; + for(int i = 0; i != nums.size(); ++i) + { + if(nums[i] != val) + { + nums[index++] = nums[i]; + } + } + return index; + } +}; +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/27/note_Yac836.md b/leetcode/27/note_Yac836.md new file mode 100644 index 0000000..3614fdb --- /dev/null +++ b/leetcode/27/note_Yac836.md @@ -0,0 +1,47 @@ +## 链接 + + +https://leetcode.com/problems/remove-element/ + + +## 解题思路 + +1. 定义一个计数器,作用有二 + ++ 记录有几个目标值 ++ 将不同与目标值的数字,移动到数组前面 + + + + + + + + +## 代码 + + + + + + +```c++ +int removeElement(vector& nums, int val) { + vector::size_type i = 0, j = 0; + for (;i != nums.size();i++) { + if (nums[i] == val) + continue; + nums[j] = nums[i]; + j++; + } + return j; +} +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/27/note_leakey.md b/leetcode/27/note_leakey.md new file mode 100644 index 0000000..bac5e7b --- /dev/null +++ b/leetcode/27/note_leakey.md @@ -0,0 +1,59 @@ +## 链接 + + +https://leetcode.com/problems/remove-element/ + + +## 题目 + + + + + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { +public: + int removeElement(vector& nums, int val) { + vector::iterator n; + for (n = nums.begin(); n != nums.end();) + if (*n == val) + n = nums.erase(n); // del the element and return to the next position of deleted element + else + n++; + return nums.size(); + } +}; + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git a/leetcode/37/note.md b/leetcode/37/note.md new file mode 100644 index 0000000..d6e0bb2 --- /dev/null +++ b/leetcode/37/note.md @@ -0,0 +1,56 @@ +## 链接 + +37.Sudoku Solver(Hard) + +## 题目 + +Write a program to solve a Sudoku puzzle by filling the empty cells. + +Empty cells are indicated by the character `'.'`. + +You may assume that there will be only one unique solution. + +![img](http://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Sudoku-by-L2G-20050714.svg/250px-Sudoku-by-L2G-20050714.svg.png) + +A sudoku puzzle... + +![img](http://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Sudoku-by-L2G-20050714_solution.svg/250px-Sudoku-by-L2G-20050714_solution.svg.png) + +...and its solution numbers marked in red. + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/41/note.md b/leetcode/41/note.md new file mode 100644 index 0000000..20029b6 --- /dev/null +++ b/leetcode/41/note.md @@ -0,0 +1,50 @@ +## 链接 + +41.First Missing Positive(Hard) + +## 题目 + +Given an unsorted integer array, find the first missing positive integer. + +For example, +Given `[1,2,0]` return `3`, +and `[3,4,-1,1]` return `2`. + +Your algorithm should run in *O*(*n*) time and uses constant space. + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/41/note_bajdcc.md b/leetcode/41/note_bajdcc.md new file mode 100644 index 0000000..d2c6bb1 --- /dev/null +++ b/leetcode/41/note_bajdcc.md @@ -0,0 +1,90 @@ +## 链接 + +41.First Missing Positive(Hard) + +## 题目 + +Given an unsorted integer array, find the first missing positive integer. + +For example, +Given `[1,2,0]` return `3`, +and `[3,4,-1,1]` return `2`. + +Your algorithm should run in *O*(*n*) time and uses constant space. + + + +## 方法一:排序查缺法 + +思路:将原数组排序,然后从前向后查找缺漏的,不过此方法复杂度为线性对数阶,不满足题意,但也能AC。 + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + +class Solution { +public: + int firstMissingPositive(vector &nums) { + sort(nums.begin(), nums.end()); + auto min = 1; + for (auto &n : nums) { + if (n > 0) { + if (n == min) + min++; + else if (n > min) + return min; + } + } + return min; + } +}; +``` + +## 方法二:按位置换法 + +听说过希尔伯特旅馆悖论吧?那么这里,从前往后遍历nums,数组大小len,设当前为n。 + +这时思考,如果n<=0或者n>len,那么n必然是无效的。在这个范围内(1~len)的n,把它们放到nums[n-1]的位置上。 + +问题来了:新的位置上又有其他数字怎么办呢?答案是用递归去解决。递归解决后然后再置换。 + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + +class Solution { +public: + int firstMissingPositive(vector &nums) { + for (auto &n : nums) { + firstMissingPositive(nums, n); + } + for (int i = 0; i < nums.size(); ++i) { + if (nums[i] != -2333) + return i + 1; + } + return nums.size() + 1; + } + + void firstMissingPositive(vector &nums, int& n) { + if (n > 0 && n <= nums.size()) { + auto j = nums[n-1], &k = nums[n-1]; + if (j < 1) { + k = -2333; + } else if (j != -2333) { + k = -666; + firstMissingPositive(nums, j); + k = -2333; + } + } + } +}; +``` + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/51/note.md b/leetcode/51/note.md new file mode 100644 index 0000000..14feca9 --- /dev/null +++ b/leetcode/51/note.md @@ -0,0 +1,67 @@ +## 链接 + +51.N-Queens(Hard) + +## 题目 + +The *n*-queens puzzle is the problem of placing *n* queens on an *n*×*n* chessboard such that no two queens attack each other. + +![img](http://www.leetcode.com/wp-content/uploads/2012/03/8-queens.png) + +Given an integer *n*, return all distinct solutions to the *n*-queens puzzle. + +Each solution contains a distinct board configuration of the *n*-queens' placement, where `'Q'` and `'.'` both indicate a queen and an empty space respectively. + +For example, +There exist two distinct solutions to the 4-queens puzzle: + +``` +[ + [".Q..", // Solution 1 + "...Q", + "Q...", + "..Q."], + + ["..Q.", // Solution 2 + "Q...", + "...Q", + ".Q.."] +] +``` + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/65/note.md b/leetcode/65/note.md new file mode 100644 index 0000000..d9f2e33 --- /dev/null +++ b/leetcode/65/note.md @@ -0,0 +1,53 @@ +## 链接 + +65.Valid Number(Hard) + +## 题目 + +Validate if a given string is numeric. + +Some examples: +`"0"` => `true` +`" 0.1 "` => `true` +`"abc"` => `false` +`"1 a"` => `false` +`"2e10"` => `true` + +**Note:** It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one. + +## 释义 + + + + + + +## 补充描述 + + + + + + +## 代码 + + + + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 \ No newline at end of file diff --git a/leetcode/65/note_bajdcc.md b/leetcode/65/note_bajdcc.md new file mode 100644 index 0000000..3cc5c9a --- /dev/null +++ b/leetcode/65/note_bajdcc.md @@ -0,0 +1,244 @@ +## 链接 + +65.Valid Number(Hard) + +## 题目 + +Validate if a given string is numeric. + +Some examples: +`"0"` => `true` +`" 0.1 "` => `true` +`"abc"` => `false` +`"1 a"` => `false` +`"2e10"` => `true` + +**Note:** It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one. + +## 思路 + +这是数字的匹配,一般涉及编译原理的题目都是hard难度。一般而言,可以采用多重嵌套if判断的方法解决,不过这样没有挑战性,代码也丑,能不能另辟蹊径呢? + +**下面的方法非典型,初学者会感到吃力**。要学会这种方法,需要熟练掌握正则表达式的使用,以及一定的编译原理基础。 + +正则表达式可以表示3型文法,它有一定的语法结构,这样不细说。像电子邮件、网址、电话号码、用户名等都可以用正则表达式进行匹配。而正则表达式常用的功能也就是匹配或者捕获。 + +这里,数字的正则表达式是`[ ]*[+-]?(\d*\.?\d+|\d+\.?\d*)([e][+-]?\d+)?[ ]*`。 + +既然是3型文法,那就可以用确定性有限自动机来表示。根据常用方法,要先画出NFA,然后去epsilon边,再进行最小化,那么这里不可能写出这么复杂的代码,因此我偷懒了 :) + +参见自己的[解释库](https://github.com/bajdcc/jMinilang)中的正则匹配部分`priv.bajdcc.util.lexer.test.TestRegex`,直接运行它,然后输入上述正则表达式,那么具体信息就出来了。 + +详细信息(程序自动生成): + +```c++ +#### 正则表达式语法树 #### +序列 { + 循环{0,-1} { + 字符 [\u0020,' '] + } + 循环{0,1} { + 字符 [\u002b,'+'],[\u002d,'-'] + } + 分支 { + 序列 { + 循环{0,-1} { + 字符 [\u0030,'0']-[\u0039,'9'] + } + 循环{0,1} { + 字符 [\u002e,'.'] + } + 循环{1,-1} { + 字符 [\u0030,'0']-[\u0039,'9'] + } + } + 序列 { + 循环{1,-1} { + 字符 [\u0030,'0']-[\u0039,'9'] + } + 循环{0,1} { + 字符 [\u002e,'.'] + } + 循环{0,-1} { + 字符 [\u0030,'0']-[\u0039,'9'] + } + } + } + 循环{0,1} { + 序列 { + 字符 [\u0065,'e'] + 循环{0,1} { + 字符 [\u002b,'+'],[\u002d,'-'] + } + 循环{1,-1} { + 字符 [\u0030,'0']-[\u0039,'9'] + } + } + } + 循环{0,-1} { + 字符 [\u0020,' '] + } +} + +#### 状态集合 #### +[\u0020,' '] +[\u002b,'+'] +[\u002d,'-'] +[\u002e,'.'] +[\u0030,'0']-[\u0039,'9'] +[\u0065,'e'] +#### 最小化 #### +状态[0] => 0, + 边 => [1] + 类型 => 字符区间 [\u0030,'0']-[\u0039,'9'] + 边 => [0] + 类型 => 字符区间 [\u0020,' '] + 边 => [2] + 类型 => 字符区间 [\u002e,'.'] + 边 => [3] + 类型 => 字符区间 [\u002b,'+'] + 边 => [3] + 类型 => 字符区间 [\u002d,'-'] +状态[1][结束] => 3,4,6, + 边 => [4] + 类型 => 字符区间 [\u002e,'.'] + 边 => [5] + 类型 => 字符区间 [\u0065,'e'] + 边 => [6] + 类型 => 字符区间 [\u0020,' '] + 边 => [1] + 类型 => 字符区间 [\u0030,'0']-[\u0039,'9'] +状态[2] => 5, + 边 => [7] + 类型 => 字符区间 [\u0030,'0']-[\u0039,'9'] +状态[3] => 2, + 边 => [2] + 类型 => 字符区间 [\u002e,'.'] + 边 => [1] + 类型 => 字符区间 [\u0030,'0']-[\u0039,'9'] +状态[4][结束] => 5,8, + 边 => [5] + 类型 => 字符区间 [\u0065,'e'] + 边 => [6] + 类型 => 字符区间 [\u0020,' '] + 边 => [4] + 类型 => 字符区间 [\u0030,'0']-[\u0039,'9'] +状态[5] => 10, + 边 => [8] + 类型 => 字符区间 [\u0030,'0']-[\u0039,'9'] + 边 => [9] + 类型 => 字符区间 [\u002b,'+'] + 边 => [9] + 类型 => 字符区间 [\u002d,'-'] +状态[6][结束] => 11, + 边 => [6] + 类型 => 字符区间 [\u0020,' '] +状态[7][结束] => 6, + 边 => [5] + 类型 => 字符区间 [\u0065,'e'] + 边 => [7] + 类型 => 字符区间 [\u0030,'0']-[\u0039,'9'] + 边 => [6] + 类型 => 字符区间 [\u0020,' '] +状态[8][结束] => 14, + 边 => [6] + 类型 => 字符区间 [\u0020,' '] + 边 => [8] + 类型 => 字符区间 [\u0030,'0']-[\u0039,'9'] +状态[9] => 13, + 边 => [8] + 类型 => 字符区间 [\u0030,'0']-[\u0039,'9'] + +#### 状态转移矩阵 #### + 0 3 3 2 1 -1 + 6 -1 -1 4 1 5 + -1 -1 -1 -1 7 -1 + -1 -1 -1 2 1 -1 + 6 -1 -1 -1 4 5 + -1 9 9 -1 8 -1 + 6 -1 -1 -1 -1 -1 + 6 -1 -1 -1 7 5 + 6 -1 -1 -1 8 -1 + -1 -1 -1 -1 8 -1 +``` + +## 代码 + +利用DFA状态转移表进行匹配。 + + +```c++ + +//代码放在这个块里面,可以高亮关键字 +class Solution { + inline int getCharMap(const char& c) { + switch (c) { + case ' ': + return 0; + case '+': + return 1; + case '-': + return 2; + case '.': + return 3; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return 4; + case 'e': + return 5; + } + return -1; + } + +public: + bool isNumber(string s) { + using t = int(*)[6]; + int mm[] = { + 0 ,3 ,3 ,2 ,1 ,-1, + 6 ,-1 ,-1 ,4 ,1 ,5, + -1 ,-1 ,-1 ,-1 ,7 ,-1, + -1 ,-1 ,-1 ,2 ,1 ,-1, + 6 ,-1 ,-1 ,-1 ,4 ,5, + -1 ,9 ,9 ,-1 ,8 ,-1, + 6 ,-1 ,-1 ,-1 ,-1 ,-1, + 6 ,-1 ,-1 ,-1 ,7 ,5, + 6 ,-1 ,-1 ,-1 ,8 ,-1, + -1 ,-1 ,-1 ,-1 ,8 ,-1, + }; + auto m = (t)mm; + bool final[] = {0, 1, 0, 0, 1, 0, 1, 1, 1, 0}; + int status = 0; + auto c = s.c_str(); + for (;;) { + auto local = *c++; + int charClass = getCharMap(local); + int refer = -1; + if (charClass != -1) { + refer = m[status][charClass]; + } + if (refer == -1) { + return local == 0 && final[status]; + } else { + status = refer; + } + } + } +}; + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。 diff --git "a/primer/\351\224\231\350\257\257\350\241\250.md" "b/primer/\351\224\231\350\257\257\350\241\250.md" new file mode 100644 index 0000000..6777f16 --- /dev/null +++ "b/primer/\351\224\231\350\257\257\350\241\250.md" @@ -0,0 +1,17 @@ + + +## P330 + +表9.19 + +> q.pop() 返回queue的首元素或(),但不删除此元素 + +参考cppreference + +http://en.cppreference.com/w/cpp/container/queue/pop + +pop执行**删除首元素**的操作。 +##P470 +练习 13.41 + +>为什么在construct调用中使用**前置**递增运算符? diff --git "a/\347\255\224\351\242\230\346\240\274\345\274\217_\344\270\215\350\246\201\344\277\256\346\224\271\346\255\244\346\226\207\344\273\266.md" "b/\347\255\224\351\242\230\346\240\274\345\274\217_\344\270\215\350\246\201\344\277\256\346\224\271\346\255\244\346\226\207\344\273\266.md" new file mode 100644 index 0000000..99d9a83 --- /dev/null +++ "b/\347\255\224\351\242\230\346\240\274\345\274\217_\344\270\215\350\246\201\344\277\256\346\224\271\346\255\244\346\226\207\344\273\266.md" @@ -0,0 +1,48 @@ +## 链接 + + +这里更新本次题目的链接 + + +## 题目 + +这里对题目做出翻译 + + + +## 释义 + +对该题目的理解 + + + + +## 补充描述 + + +有其他思路等可以写在这里 + + + +## 代码 + + +具体的实现代码放这,如果有多个实现,可复制该块多份,并添加编号,如“## 代码1” + + + +```c++ + +//代码放在这个块里面,可以高亮关键字 + + + +``` + + + +## 更多 + +![](https://github.com/githubwoniu/learnprogram/blob/master/image/erweima.png) + +PS: 请保留二维码链接,以便更多人参与进来。谢谢。