牛客剑指offer刷题记录
Posted NearXDU
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客剑指offer刷题记录相关的知识,希望对你有一定的参考价值。
连续子数组最大和
动态规划的题目,定义dp(i)
是以第i个数字结尾的子数组的最大和,那么有如下动态规划方程:
dp(i)=num(i),i=0或者dp(i−1)<=0
dp(i)=dp(i−1)+num(i),i>0且dp(i−1)>0
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;
;
当然也可以用局部最优和全局最优的方式来做,局部最优保证以当前数字结尾,的最大值那么有:
local(i)=max(local(i−1)+num(i),num(i))
然后求全局最优:
global(i)=max(local(i),global(i−1))
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;
;
以上是关于牛客剑指offer刷题记录的主要内容,如果未能解决你的问题,请参考以下文章