本文专注于分享如何利用AI刷题的思路历程,以“找出整形数组中的占比超过一半的数”为例,讲解怎样用AI提升代码能力,将问题从能够解决优化到最优解的过程。
问题描述
小R从班级中抽取了一些同学,每位同学都会给出一个数字。已知在这些数字中,某个数字的出现次数超过了数字总数的一半。现在需要你帮助小R找到这个数字。
测试样例
样例1:
输入:
array = [1, 3, 8, 2, 3, 1, 3, 3, 3]
输出:3
样例2:
输入:
array = [5, 5, 5, 1, 2, 5, 5]
输出:5
样例3:
输入:
array = [9, 9, 9, 9, 8, 9, 8, 8]
输出:9
思路由来
生活中,面对不同的问题、困难,难的往往是开始——对问题的手足无措,思绪混乱。同样在我们刷题的过程中,最难的也是开始——思路何来?
读题是关键
为了理清思路,读题是关键。我们要在问题描述中,明确输入、输出和我们要做的处理。 像本文的例子:
-
输入:小R从班级中抽取了一些同学,每位同学都会给出一个数字。
-
输出:现在需要你帮助小R找到这个数字。
-
处理:已知在这些数字中,某个数字的出现次数超过了数字总数的一半。
当我们明确输入,输出和处理后,如何解决问题便一目了然。这个例子中,我们要在一个整形数组中,找到超过数字总数一半的数,然后输出它。对这个问题,我立马想出来的就是暴力法:遍历这个数组,选择一个数,拿这个数和数组中的数一一比较,相等则count++,输出count大于总数一半的数。
int solution(vector<int> array) {
int count = 0;
for(int a : array){
for(int b : array){
if (a == b ){
count++;
}
}
if(count > array.size()/2){
return a;
}
}
}
利用AI优化并学习
很明显这里采用了双层for循环,时间复杂度O(N^2)。当问题规模较大的时候,往往会超时。那该如何优化呢?没有AI时,我们往往要在网上搜来搜去,找方法,学习他人的例子,然后再处理自己的问题。但是AI出现后,我们就可以结合自己的问题问AI了。像下面这样:
- 用户:帮我检查一下编辑区的代码
- AI:好的,让我们来检查一下你编辑区的代码,看看是否存在问题以及如何改进。
效率问题:
- 你使用了双重循环,时间复杂度为 (O(n^2)),效率较低。
- 解决方法:可以使用摩尔投票算法来优化,时间复杂度为 (O(n))。
AI会结合问题,分析你的代码,给出优化意见和解决方法。然后我们就可以接着问如何实现。AI就会给出代码和解释。我们根据解析学习新的算法。
-
摩尔投票算法:
- 初始化
candidate和count。 - 遍历数组中的每个元素:
- 如果
count为 0,将当前元素设为candidate。 - 如果当前元素与
candidate相同,count加一;否则,count减一。
- 如果
- 最终的
candidate就是出现次数超过一半的元素。
- 初始化
-
时间复杂度:
- 摩尔投票算法的时间复杂度为 (O(n)),空间复杂度为 (O(1)),效率更高。
#include <iostream>
#include <vector>
using namespace std;
int solution(vector<int> array) {
int candidate = 0;
int count = 0;
// 摩尔投票算法
for (int num : array) {
if (count == 0) {
candidate = num;
}
if (num == candidate) {
count++;
} else {
count--;
}
}
return candidate;
}
int main() {
cout << (solution({1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3) << endl;
return 0;
}
总结
很明显,题目采用摩尔投票算法的时间复杂度为O(N),空间复杂度为O(1),比我一开始使用的暴力法好。这样我们就通过刷题结合AI优化,学习了新的思路和方法,提高了算法能力。