第一道
题目名称:152. Maximum Product Subarray
题目难度:Medium
题目描述:Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array [2,3,-2,4]
,
the contiguous subarray [2,3]
has the largest product = 6.
题目分析:
题目要求我们找出乘积最大的相邻子串。子串的长度不定,只要相邻就行。
一开始博主理解错了题目的意思,以为相邻就是最大长度为3,结果秒写出的算法WA了。才发现是任何长度都行。
那么这就是一个动态规划问题了。思路大概是这样的:
从第一位到当前位的最大乘积和前面的数有什么关系呢?即imax[i]与imax[i-1]有什么关系吗?观察可以发现包括当前数字的乘积最大的子串要不就是这个数自己本身组成的子串,要不就是跟之前的将这个数加入前一个数的最长子串之后得到的新的长子串。即imax[i] = max(imax[i-1] * nums[i], nums[i])
思路大概是这样的,但是这道题有一个比较特殊的点,就是nums数组里面可能有负数。如果当前数字是负数的话,他的最大值就要他自己本身以及他乘以他前一位的最小值之间来比较了。所以写程序的时候这一点要留点心。
最后AC的代码是:
class Solution {
public:
int maxProduct(vector<int>& nums) {
int imax = nums[0];
int tMax = 1, tMin = 1;
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] < 0) {
swap(tMax, tMin);
}
tMax = max(nums[i], nums[i] * tMax);
tMin = min(nums[i], nums[i] * tMin);
if (tMax > imax) imax = tMax;
}
return imax;
}
};
第二道
题目名称:152. Maximum Product Subarray
题目难度:Medium
题目描述:Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
题目分析:
这道题要求我们找出一个数组中唯一一个只出现了一次的数,其他的数都出现了3次。而且要求算法的时间复杂度应该为O(n),最好不要使用额外的空间。
想了半天想不到比较符合要求的算法。
然后按照自己的思路写了一个时间复杂度为O(nlogn),使用了一个额外空间的算法。
思路很简单,直接使用快排在原地排序,然后按顺序遍历便可以找到这个数了。
最后居然AC了,可能这道题对复杂度的检查没有那么严格。
int singleNumber(vector<int>& nums) {
if (nums.size() == 1) return nums[0];
sort(nums.begin(), nums.end());
for (int i = 0 ;i < nums.size(); ++i) {
cout << nums[i] << ' ';
}
cout << endl;
for (int i = 0; i < nums.size() - 1; ) {
if (nums[i] == nums[i+1]) {
i += 3;
if (i == nums.size() - 1)
return nums[i];
} else {
return nums[i];
}
}
return 0;
}
完成之后在本题的讨论区看到一个看起来很高级的算法:
public int singleNumber(int[] A) {
int ones = 0, twos = 0;
for(int i = 0; i < A.length; i++){
ones = (ones ^ A[i]) & ~twos;
twos = (twos ^ A[i]) & ~ones;
}
return ones;
}
不过看了半天没怎么理解 = =