[Leetcode]667.Beautiful Arrangement II
链接:LeetCode667
给定两个整数 n 和 k,你需要实现一个数组,这个数组包含从 1 到 n 的 n 个不同整数,同时满足以下条件:
① 如果这个数组是,那么数组中应该有且仅有 k 个不同整数;.
② 如果存在多种答案,你只需实现并返回其中任意一种.
示例 1:
输入: n = 3, k = 1
输出:
解释: 包含 3 个范围在 1-3 的不同整数, 并且 中有且仅有 1 个不同整数 : 1
这道题真实诠释了什么是思考一小时,解题一分钟。遇到这种题,明显无法通过数据结构和常用的算法技巧来解,我们需要通过多次尝试,找规律才能发现解法。我们用一个例子来分析,比如说当n=8,我们有数组:
1, 2, 3, 4, 5, 6, 7, 8
当我们这样有序排列的话,相邻两数的差的绝对值为1。我们想差的绝对值最大能为多少,应该是把1和8放到一起,为7。那么为了尽可能的产生不同的差的绝对值,我们在8后面需要放一个小数字,比如2,这样会产生差的绝对值6,同理,后面再跟一个大数,比如7,产生差的绝对值5,以此类推,我们得到下列数组:
1, 8, 2, 7, 3, 6, 4, 5
其差的绝对值为:7,6,5,4,3,2,1
共有7种,所以我们知道k最大为n-1,所以这样的排列一定会存在。我们的策略是,先按照这种最小最大数相邻的方法排列,没排一个,k自减1,当k减到1的时候,后面的排列方法只要按照生序的方法排列,就不会产生不同的差的绝对值,这种算法的时间复杂度是O(n),属于比较高效的那种。我们使用两个指针,初始时分别指向1和n,然后分别从i和j取数加入结果res,每取一个数字k自减1,直到k减到1的时候,开始按升序取后面的数字。
另外,还有一种解法是将数组不停翻转即可。代码如下:
python:
class Solution:
def constructArray(self, n: int, k: int) -> List[int]:
nums = list(range(1,n+1))
for i in range(k):
nums[i:] = nums[i:][::-1]
return nums
C++:
class Solution {
public:
vector<int> constructArray(int n,int k){
vector<int> res;
int i=1,j=n;
while(i<=j){
if(k>1) res.push_back(k--%2 ? i++ : j--);
else res.push_back(i++);
}
return res;
}
vector<int> constructArray2(int n, int k) {
vector<int> nums;
for(int i=1;i<=n;++i){
nums.push_back(i);
}
for(int i=0;i<k;++i){
reverse(nums.begin()+i,nums.end());
}
return nums;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)