答题实践笔记
题目解析
题目描述:
小F手中有一串数字,他希望这些数字能按照一定的规则两两配对。配对的规则如下:
- 数字对中的两个数字的差的绝对值必须大于等于给定的差异值M。
- 每个数字只能被配对一次,不能出现在其他的数字对中。
- 小F想知道给定的数字中,最多能成功配对出多少对数字。
示例:
- 输入:
N = 4, M = 2, X = [1, 3, 3, 7] - 输出:
2
思路分析:
要在数组中找到最多的数字对,使得每对数字的差的绝对值大于等于M,且每个数字只能使用一次。为了实现这个目标,我们需要:
-
排序数组:将数组从小到大排序,方便比较数字之间的差值。
-
双指针技巧:使用两个指针
left和right,分别指向数组的不同部分,以便快速找到符合条件的数字对。 -
贪心策略:尽可能地匹配最小的数字对,以保证后续还有更多的数字可以配对。
图解说明:
假设排序后的数组为[1, 3, 3, 7],差异值M = 2。
索引: 0 1 2 3
值: [1, 3, 3, 7]
- 初始化
left = 0(指向1),right = 2(指向第二个3)。 - 比较
X[right] - X[left] = 3 - 1 = 2 >= M,可以配对,count++,left++,right++。 - 现在
left = 1(指向第一个3),right = 3(指向7)。 - 比较
X[right] - X[left] = 7 - 3 = 4 >= M,可以配对,count++,left++,right++。 - 指针越界,结束循环。
代码详解:
#include <iostream>
#include <vector>
#include <algorithm>
int solution(int N, int M, std::vector<int> X) {
// 将数组排序
std::sort(X.begin(), X.end());
// 初始化指针和计数器
int left = 0;
int right = N / 2;
int count = 0;
// 使用双指针遍历数组
while (left < N / 2 && right < N) {
if (X[right] - X[left] >= M) {
// 找到符合条件的配对
count++;
left++;
right++;
} else {
// 不符合条件,移动右指针寻找下一个可能的数字
right++;
}
}
return count;
}
int main() {
std::vector<int> arr1 = {1, 3, 3, 7};
std::cout << solution(4, 2, arr1) << std::endl; // 输出:2
return 0;
}
代码解释:
- 排序:为了方便比较,首先对数组进行排序。
- 初始化:
left从数组起始位置开始,right从数组中间位置开始。 - 循环条件:
left小于N / 2且right小于N,确保指针不越界。 - 判断配对:
- 如果
X[right] - X[left] >= M,则找到一对符合条件的数字,计数器加一,left和right同时移动到下一个位置。 - 如果不满足条件,
right右移,继续寻找。
- 如果
知识总结
1. 贪心算法:
贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。
- 应用场景:求解最优化问题,如最大化或最小化某种资源的使用。
- 特点:不回溯,不考虑所有可能的情况,只关注当前最优解。
2. 双指针技巧:
双指针是一种常用的数组遍历方法,通常用于有序数组,可以高效地解决一类问题。
- 前提条件:数组有序或部分有序。
- 用途:查找满足特定条件的元素对或子数组。
学习建议:
- 理解排序的重要性:排序往往是解决数组问题的第一步,可以降低问题的复杂度。
- 熟练掌握双指针:多练习使用双指针解决问题,如两数之和、三数之和等经典问题,这些在掘金里面被包装了一个背景,如果想直接找原题可以去leetcode。
- 练习贪心算法:理解贪心算法的思想,在实践中体会其应用场景和局限性。
学习计划
1. 制定刷题计划:
- 每日一题:不用说坚持每天至少解决一道算法题,但是还是要坚持,不能停很久,要逐步提升算法思维。
- 分类练习:按主题(如贪心、双指针、动态规划等)进行专项练习,深入理解各类算法思想,可以看看代码随想录。
2. 利用错题进行针对性学习:
- 错题整理:将做错的题目记录下来,分析错误原因。
- 定期复习:秋招或者找实习之前每周复习错题,巩固薄弱环节。
- 反思总结:总结解题思路,寻找更优的解法。
工具运用
1. 结合AI助手:
- 寻求解题思路:在遇到困难时,可以借助豆包AI助手获取提示和思路,但不要直接依赖答案。
- 代码审查:让AI帮助检查代码中的潜在错误,优化代码效率。
- 主动思考:在求助AI或他人之前,先自己尝试解决问题,培养独立思考能力。
- 合理使用工具:将AI和其他资源作为辅助工具,而非依赖,注重自身能力的提升。