面试题 16.11. 跳水板

​传送门​

思路:

一开始的想法是用一个 m a p map map去重,然后暴力枚举 k + 1 k+1 k+1种情况排序即可。

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)

class Solution {
public:
vector<int> divingBoard(int shorter, int longer, int k) {
vector<int>ans;
unordered_map<int,int>mp;
if(!k) return ans;
for(int i=0;i<=k;i++)
{
int x=i*shorter+(k-i)*longer;
if(!mp[x]) mp[x]=1,ans.push_back(x);
}
sort(ans.begin(),ans.end());
return ans;
}
};

后来发现只需讨论一下即可。

为了方便讨论,我们令 x = s h o r t e r , y = l o n g e r x=shorter,y=longer x=shorter,y=longer

1. k = = 0 k==0 k==0,返回空数组。

2. k ≠ 0 , x = y k\neq0,x=y k=0,x=y时,显然只有一种情况,返回 { k × x } \{k\times x\} {k×x}

3. k ≠ 0 , x < y k\neq0,x<y k=0,x<y时,假设对任意 2 2 2种情况分别选择了 i i i和 j j j个 x x x,可以默认 i < j i<j i<j(等价性)

则对于

i : a n s = x i + ( k − i ) y j : a n s = x j + ( k − j ) y a n s j − a n s i = x ( j − i ) + y ( i − j ) = ( y − x ) ( i − j ) < 0 i:ans=xi+(k-i)y\\j:ans=xj+(k-j)y\\ans_j-ans_i=x(j-i)+y(i-j)=(y-x)(i-j)<0 i:ans=xi+(k−i)yj:ans=xj+(k−j)yansj−ansi=x(j−i)+y(i−j)=(y−x)(i−j)<0

说明选择 y y y的个数越多,答案越大,且任意两种情况答案不会相同,所以我们可以确切知道有 k + 1 k+1 k+1种情况,所以按照 y y y的个数从小到大把数存入数组即可。

时间复杂度: O ( k ) O(k) O(k)

class Solution {
public:
vector<int> divingBoard(int x, int y, int k) {
vector<int>ans;
if(!k) return {};
if(x==y){
return {x*k};
}
for(int i=0;i<=k;i++){
ans.push_back((k-i)*x+i*y);
}
return ans;
}
};