《数轴上的石子游戏》
题面
问题理解
题目要求我们通过最少的移动次数,使得三枚石子的位置连续。具体来说,就是将三个位置 a, b, c 调整为连续的三个整数。
数据结构选择
通过 vector<int> 来存储这三个位置,并通过 sort 函数对它们进行排序。
算法步骤
-
排序:首先对三个位置进行排序,使得
nums[0] <= nums[1] <= nums[2]。 -
判断连续性:
- 如果
nums[0] + 1 == nums[1]且nums[1] + 1 == nums[2],说明三个位置已经连续,不需要任何移动,返回0。 - 如果
nums[0] + 1 == nums[1]或nums[1] + 1 == nums[2],说明有一个位置已经连续,只需要移动一次即可,返回1。 - 如果
nums[0] + 2 == nums[1]或nums[1] + 2 == nums[2],说明有一个位置只差一个单位就可以连续,也只需要移动一次,返回1。 - 其他情况,说明至少需要移动两次才能使三个位置连续,返回
2。
- 如果
具体实现
int solution(int a, int b, int c) {
// 将三个位置存储到 vector 中并排序
vector<int> nums = {a, b, c};
sort(nums.begin(), nums.end());
// 判断是否已经连续
if (nums[0] + 1 == nums[1] && nums[1] + 1 == nums[2]) {
return 0;
}
// 判断是否只需要移动一次
else if (nums[0] + 1 == nums[1] || nums[1] + 1 == nums[2] ||
nums[0] + 2 == nums[1] || nums[1] + 2 == nums[2]) {
return 1;
}
// 其他情况,至少需要移动两次
else {
return 2;
}
}
《数组长度缩减到1》
题面
问题理解
题目要求我们判断是否可以通过若干次操作将数组 A 缩减到长度为 1。每次操作可以选择一个索引 i,如果 A[i] 和 A[i+1] 都小于 X,则可以将这两个元素移除,并在它们的位置插入它们的和。
数据结构选择
通过 std::stack 来处理数组元素。栈是一种后进先出(LIFO)的数据结构,适合用于处理需要反向操作的场景。
算法步骤
- 初始化栈:将数组
A中的元素依次压入栈中。 - 合并操作:每次由栈中取出一个元素
cur,然后检查栈顶元素是否可以与cur合并(即两者之和小于X)。如果可以,则合并并继续检查;否则,将cur压回栈中。 - 最终判断:如果栈中只剩下一个元素,则返回
1,表示可以缩减到长度为1;否则返回0。
具体实现
int solution(int N, int X, std::vector<int>& A) {
if(N == 1) {
return 0; // 如果数组长度为1,直接返回0(这里有争议,我个人其实更偏向于返回1)
}
std::stack<int> stk;
for(int i : A) {
stk.push(i); // 将当前元素压入栈中
int cur = stk.top(); // 取出栈顶元素
stk.pop(); // 弹出栈顶元素
while(!stk.empty() && cur + stk.top() < X) {
// 如果栈非空且栈顶元素与cur的和小于X,则合并
cur += stk.top();
stk.pop();
}
stk.push(cur); // 将合并后的元素压回栈中
}
int a = stk.top(); // 取出栈顶元素
stk.pop();
if(stk.empty()) {
return 1; // 如果栈为空,说明数组可以缩减到长度为1
}
int b = stk.top(); // 取出栈顶元素
stk.pop();
if(!stk.empty()) {
return 0; // 如果栈中还有元素,说明数组无法缩减到长度为1
}
return a < X && b < X; // 检查最后两个元素是否都小于X
}
《最低成本清空数组》
题面
问题理解
题目要求我们通过一系列迭代操作将数组清空,每次迭代中必须删除K个值相同的元素。每次迭代的成本为 T * V,其中T是迭代的次数,V是被删除元素的值。目标是找到清空数组的最低成本。如果不可能清空数组,则返回-1。
数据结构选择
通过std::vector来存储数组A,并通过std::sort对数组进行排序。排序的目的是为了更容易地找到相同值的元素,并进行批量删除。
算法步骤
- 排序:首先对数组
A进行排序,这样相同值的元素会聚集在一起。 - 检查数组长度是否能被
K整除:如果数组长度N不能被K整除,说明无法通过每次删除K个元素来清空数组,直接返回-1。 - 迭代删除:由数组的末尾开始,每次删除
K个元素。如果当前K个元素的值不相同,则返回-1,表示无法清空数组。否则,计算当前迭代的成本并累加到总成本中。
具体实现
int solution(int N, int K, std::vector<int> A) {
int ret = 0;
sort(A.begin(), A.end());
if (N % K != 0) {
return -1;
}
for (int i = N - 1; i >= 0; i -= K) {
if (A[i] != A[i - K + 1]) {
return -1;
}
ret += (N - i - 1 + K) / K * A[i];
}
return ret;
}