7整数反转
class Solution {
public:
int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
if (rev > INT_MAX/10 || (rev == INT_MAX / 10 && pop > 7)) return 0;
if (rev < INT_MIN/10 || (rev == INT_MIN / 10 && pop < -8)) return 0;
rev = rev * 10 + pop;
}
return rev;
}
};
9回文数
我的解答
class Solution {
public:
bool isPalindrome(int x) {
int halfRev = 0;
//注意特殊用例
if(x < 0 || (x % 10 == 0) && x !=0)
return false;
if(x < 10)
return true;
while(x/10 >= halfRev*10)
{
halfRev = halfRev*10 + x % 10;
x /= 10;
}
return x == halfRev || x/10 == halfRev;
}
};
算法
首先,我们应该处理一些临界情况。所有负数都不可能是回文,例如:-123 不是回文,因为 - 不等于 3。所以我们可以对所有负数返回 false。
现在,让我们来考虑如何反转后半部分的数字。 对于数字 1221,如果执行 1221 % 10,我们将得到最后一位数字 1,要得到倒数第二位数字,我们可以先通过除以 10 把最后一位数字从 1221 中移除,1221 / 10 = 122,再求出上一步结果除以10的余数,122 % 10 = 2,就可以得到倒数第二位数字。如果我们把最后一位数字乘以10,再加上倒数第二位数字,1 * 10 + 2 = 12,就得到了我们想要的反转后的数字。 如果继续这个过程,我们将得到更多位数的反转数字。
现在的问题是,我们如何知道反转数字的位数已经达到原始数字位数的一半?
我们将原始数字除以 10,然后给反转后的数字乘上 10,所以,当原始数字小于反转后的数字时,就意味着我们已经处理了一半位数的数字。
lc解法
class Solution {
public:
bool isPalindrome(int x) {
int halfRev = 0;
//注意特殊用例
if(x < 0 || (x % 10 == 0) && x !=0)
return false;
while(x > halfRev)
{
halfRev = halfRev*10 + x % 10;
x /= 10;
}
return x == halfRev || x == halfRev/10;
}
};
后面三题是动态规划:
58最大子序
存储所有的历史
class Solution {
public:
int maxSubArray(vector<int>& nums){
int maxSub = INT_MIN;
int dp[nums.size()+1];
dp[0] = 0;
for(int i = 1; i < nums.size() + 1; i++)
{
dp[i-1]>0?dp[i] = dp[i-1] + nums[i-1]:dp[i] = nums[i-1];
maxSub = max(maxSub, dp[i]);
}
return maxSub;
}
};
节省存储空间,因为下一步的价值只受当前步影响:
class Solution {
public:
int maxSubArray(vector<int>& nums){
int f = 0, res = INT_MIN;
for(int i = 0; i < nums.size() ; i++)
{
f>0 ? f = f + nums[i] : f = nums[i];
res = max(f, res);
}
return res;
}
};
198打家劫舍
class Solution {
public:
int rob(vector<int>& nums) {
if(nums.size() == 0 ) return 0;
if(nums.size() == 1 ) return nums[0];
if(nums.size() == 2 ) return max(nums[0], nums[1]);
int dp[nums.size()];
dp[0] = nums[0];
dp[1] = max(nums[0], nums[1]);
int res = 0;
for(int i = 2; i < nums.size(); i++)
{
dp[i] = max(dp[i-1], dp[i-2] + nums[i]);
res = max(res, dp[i]);
// cout << res << endl;
}
return res;
}
};
简化存储空间,保留倒数1,2步
class Solution {
public:
int rob(vector<int>& nums) {
if(nums.size() == 0 ) return 0;
if(nums.size() == 1 ) return nums[0];
if(nums.size() == 2 ) return max(nums[0], nums[1]);
int fn, fn_1, fn_2;
fn_2 = nums[0];
fn_1 = max(nums[0], nums[1]);
int res = 0;
for(int i = 2; i < nums.size(); i++)
{
fn = max(fn_1, fn_2 + nums[i]);
res = max(res, fn);
fn_2 = fn_1;
fn_1 = fn;
// cout << res << endl;
}
return res;
}
};
121买卖股票的最佳时机
注意初始值的取值,可以省掉一些冗余的代码,思路更清晰。
比如说prices.size()为0或1的时候,都应该输出0。递减序列也要考虑
class Solution {
public:
int maxProfit(vector<int>& prices) {
int lowest = INT_MAX, maxv = 0;
for(int i = 0; i < prices.size(); i++)
{
maxv = max((prices[i] - lowest), maxv);
lowest = min(lowest, prices[i]);
}
return maxv;
}
};