面试题42. 连续子数组的最大和
题目描述: 输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
示例1:
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
提示:
1 <= arr.length <= 10^5
-100 <= arr[i] <= 100
解题思路:采用 DP
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> a) {
if(!a.size()) return 0;
int mx = 0x80000000;
for(int i = 0, s = 0; i < int(a.size()); ++i){
s = max(s + a[i], a[i]);
mx = max(mx, s);
}
return mx;
}
};
面试题43. 1~n整数中1出现的次数
题目描述: 输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数。
例如,输入12,1~12这些整数中包含1 的数字有1、10、11和12,1一共出现了5次。
示例 1:
输入:n = 12
输出:5
示例 2:
输入:n = 13
输出:6
限制:
1 <= n < 2^31
解题思路:
将原数字按10的倍数进行分割,求个、十、百....位上1的个数。以a=31415 and b=92为例,
讨论百位上1的个数,由于5是大于1的,所以当百位上出现1时,个位、十位的范围是0—99,
所以此时乘以100,而5的前面可以是0-3141,总共(3141+1)=3142个。然而当所求位上为0
和1时,其后面的位上不一定能达到0-99,这时候就考虑减1操作。
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n){
int ones = 0;
for (long long m = 1; m <= n; m *= 10)
ones += (n/m + 8) / 10 * m + (n/m % 10 == 1) * (n%m + 1);
return ones;
}
};