题目一
思路
1、就一个字,就近原则,其实是一种贪心的想法,我为了让总体次数最少,所以分给到每个人而言,就是每个人都要保证移动的次数最少,所以要找离他最近的,所以要把凳子和学生按照所在位置从小到大重排,让位置小的学生,找位置号小的座位,位置大的找位置大的。
2、i号学生找与之相对的i号作座位才能保证总移动最小,我们拿两个学生做例子如下:
不难发现,不按照上述方法,就会产生重复路径,移动次数肯定更大,在推广一下,就可以证明该方法正确性。
代码
class Solution {
public:
int minMovesToSeat(vector<int>& seats, vector<int>& students) {
int ans = 0;
sort(seats.begin(), seats.end());//重排,递增
sort(students.begin(), students.end());
int n = seats.size();
for (int i = 0; i < n; i++) {//对应位移动,保证不交叉移动
ans += abs(seats[i] - students[i]);
}
return ans;
}
};
(所有代码均已在力扣上运行无误)
经测试,该代码运行情况是(经过多次测试所得最短时间):
题目二
思路
1、我们先说一种朴素的想法,就是完全按照题意,每一次看是谁出牌,寻找相应的AAA,BBB,找到了就下一轮,听着好像可以,但是注意了,数据量有十万个,这样就会超时。
2、我们不妨抽取一下关键词,Alice找AAA,Bob找BBB,既然每一次找到一个就行,那么我们手动的统计一下,AAA和BBB个数:
1、AAA数量小于BBB,说明Alice肯定先于Bob找不到目标,return false;
2、AAA数量等于BBB,因为Alice先手,所以当最后一次Bob找完BBB后,Alice找不到了,return false
3、AAA数量大于BBB,说明Bob肯定先于Alice找不到目标,return true;
代码
class Solution {
public:
bool winnerOfGame(string colors) {
int sizes = colors.size();
int opera_A = 0, opera_B = 0;
for (int i = 0; i < sizes - 2; i++) {//统计胜点
if (colors[i] == 'A' && colors[i + 1] == 'A' && colors[i + 2] == 'A') {
opera_A++;
}
else if (colors[i] == 'B' && colors[i + 1] == 'B' && colors[i + 2] == 'B') {
opera_B++;
}
}
if (opera_A > opera_B) {
return true;
}
return false;
}
};
(所有代码均已在力扣上运行无误)
经测试,该代码运行情况是(经过多次测试所得最短时间):
时间复杂度:O(N)