坚持是一种美德。
题目一:
给你一个整数数组 nums,请你选择数组的两个不同下标 i 和 j,使 (nums[i]-1)*(nums[j]-1) 取得最大值。
请你计算并返回该式的最大值。
示例 1:
输入:nums = [3,4,5,2]
输出:12
解释:如果选择下标 i=1 和 j=2(下标从 0 开始),则可以获得最大值,(nums[1]-1)*(nums[2]-1) = (4-1)*(5-1) = 3*4 = 12 。
示例 2:
输入:nums = [1,5,4,5]
输出:16
解释:选择下标 i=1 和 j=3(下标从 0 开始),则可以获得最大值 (5-1)*(5-1) = 16 。
示例 3:
输入:nums = [3,7]
输出:12
提示:
2 <= nums.length <= 500
1 <= nums[i] <= 10^3
解题思路:这种数组内部找最大值与次大值的问题很容易想到能否通过排序去解决,插入排序、交换排序、选择排序等。最终选择了选择排序进行解题,因为选择排序每次是选择队列中最大或者最小的数出来,而这题正好是找最大值与次大值,如果选用其他排序则可能要全部排完才能找到,而如果通过选择排序则可以只排两次就能找到答案。
class Solution {
public:
int maxProduct(vector<int>& nums)
{
for(int i = 0; i < 2; i++)
{
int max = i;
for( int j = i + 1;j < nums.size(); j++)
if(nums[j] > nums [max]) max = j;
if (max!=i) swap(nums[i],nums[max]);
}
return (nums[0]-1)*(nums[1]-1);
}
};
解题完发现并没有获得最优解,而且中间发现了一个小问题,对于vector数组来说,它的长度不再是length直接表示,而是要通过.size()函数来获得,此外如果自己进行swap函数的编写可能会出现一点的error,所以推荐封装好的swap函数。
观察高赞回答:
class Solution {
public:
int maxProduct(vector<int>& nums) {
int a = nums[0], b = nums[1];
if (a < b) {
swap(a, b);
}
for (int i = 2; i < nums.size(); i++) {
if (nums[i] > a) {
b = a;
a = nums[i];
} else if (nums[i] > b) {
b = nums[i];
}
}
return (a - 1) * (b - 1);
}
};
这个回答他用两个变量a与b来保存最大值与次大值,在数组的遍历中如果出现比a大的,就把a更新,然后再让b=a;如过出现比a小比b大的,那我们就只要更新次大值b即可;如果都没a,b大,就继续向下遍历。