牛客剑指offer刷题记录(六)
来源:互联网 发布:如何防范网络陷阱 编辑:程序博客网 时间:2024/05/21 04:01
连续子数组最大和
动态规划的题目,定义dp(i)
是以第i个数字结尾的子数组的最大和,那么有如下动态规划方程:
class Solution {public: int FindGreatestSumOfSubArray(vector<int> array) { if (array.size() == 0) return 0; vector<int>dp(array.size()); int cur = numeric_limits<int>::min(); for (int i = 0; i < array.size(); ++i) { if (i == 0 || dp[i-1] <= 0) dp[i] = array[i]; if (i>0 && dp[i-1] > 0) dp[i] = dp[i - 1] + array[i]; if (dp[i] > cur) cur = dp[i]; } return cur; }};
当然也可以用局部最优和全局最优的方式来做,局部最优保证以当前数字结尾,的最大值那么有:
然后求全局最优:
class Solution {public: int FindGreatestSumOfSubArray(vector<int> array) { vector<int>a; a.swap(array); vector<int>local(a.size()); vector<int>global(a.size()); local[0] = a[0]; global[0] = a[0]; for (int i = 1; i<a.size(); ++i) { local[i] = max(a[i], local[i - 1] + a[i]); global[i] = max(local[i], global[i - 1]); } return global[a.size() - 1]; }};
从1到n整数中1出现的次数
剑指offer上面讲的不清楚。
参考:http://blog.csdn.net/yi_afly/article/details/52012593
class Solution {public: int NumberOf1Between1AndN_Solution(int n) { if (n < 0) return 0; int count = 0; int weight = 0; int round = 0; int base = 1; int origin = n; while (n > 0) { weight = n % 10; round = n / 10; if (weight == 1) { count += round*base; count += ((origin%base) + 1); } else if (weight == 0) { count += round*base; } else { count += round*base; count += base; } base *= 10; n /= 10; } return count; }};
把数组排成最小的数
希望较高位出现较小的数,需要找到一个合适的排序规则,能够在这些全排列里面筛选出最小的数。直接排序肯定是不行的,比如12,333,9
直接排序后9出现在最高位,是不符合要求的。
给出两个数字a和b需要判断哪个数在前面就要比较ab和ba
整型的拼接先转成string,然后再比较a+b和b+a
的大小
把上述规则写成比较函数,利用sort很容易:
class comp{public: bool operator()(string a, string b) { return a + b < b + a; }};class Solution {public: string PrintMinNumber(vector<int> numbers) { if (numbers.size() == 0) return string(); vector<string>n; n.reserve(numbers.size()); for(auto num : numbers) { n.push_back(to_string(num)); } sort(n.begin(), n.end(), comp()); string r; for (auto i : n) { r += i; } return r; }};
丑数
2、3、5为因数,可以写一个判断丑数的代码:
int judgeUgly(int n) { while (n % 2==0) n /= 2; while (n % 3 == 0) n /= 3; while (n % 5 == 0) n /= 5; return (n == 1) ? true : false; }
然后利用这个函数,统计n个丑数,这个办法效率较低原因在于每个数字都要进行判断一遍:
class Solution {private: bool judgeUgly(int n) { while (n % 2==0) n /= 2; while (n % 3 == 0) n /= 3; while (n % 5 == 0) n /= 5; return (n == 1) ? true : false; }public: int GetUglyNumber_Solution(int index) { int i = 1; int count = 0; while (true) { if (judgeUgly(i)) { ++count; } if (count == index) break; ++i; } return i; }};
最终超时。
效率更高的办法叫做筛选法:
首先需要一个容器,假定里面就是存放所有1-Index的丑数,第一个个丑数是1,后面所有的丑数都是前面的丑数乘上2、3、5得来的。
class Solution {public: int GetUglyNumber_Solution(int index) { vector<int>ugly(index); ugly[0] = 1; int i, j, k; i = j = k = 0; for (int count = 1; count < index; ++count) { ugly[count] = min(ugly[i] * 2, min(ugly[j] * 3, ugly[k] * 5)); if (ugly[count] == ugly[i] * 2)++i; if (ugly[count] == ugly[j] * 3)++j; if (ugly[count] == ugly[k] * 5)++k; } return ugly[index - 1]; }};
第一个只出现一次的字符
hash是最简单的解法了:
class Solution {public: int FirstNotRepeatingChar(string str) { unordered_map<char,int>m; for(int i=0;i<str.size();++i){ ++m[str[i]]; } for(int i=0;i<str.size();++i){ if(m[str[i]]==1){ return i; } } return -1; }};
阅读全文
1 0
- 牛客剑指offer刷题记录(六)
- 牛客剑指offer刷题记录(一)
- 牛客剑指offer刷题记录(二)
- 牛客剑指offer刷题记录(三)
- 牛客剑指offer刷题记录(四)
- 牛客剑指offer刷题记录(五)
- 牛客剑指offer刷题记录(七)
- 剑指offer刷题记录1
- 剑指offer刷题记录2
- 剑指offer 日常刷题记录
- 每周刷题记录(持续更新)
- OI刷题记录
- OI刷题记录~
- leetcode刷题记录
- 刷题记录
- 6.22刷题记录
- 7.26-刷题记录
- hdu 刷题记录
- 队列(Queue)
- classpath、path、JAVA_HOME的作用及JAVA环境变量配置
- windows常用的命令
- 暑期集训第一天
- eclipse更新spring后,maven选项不见了
- 牛客剑指offer刷题记录(六)
- linux初学者-常用基本命令篇
- HDU 1599: find the mincost route
- mysql sql优化
- mysql优化数据对象
- POJ 2528 Mayor's posters (线段树 区间更新+离散化)
- 关于乐视我来说两句
- 1110. Complete Binary Tree (25)
- 在windows上搭建React Native开发环境时遇到licence问题的解决