LeetCode刷题记录[1](C++)
1、存在重复元素(vector容器)
-
给你一个整数数组
nums
。如果任一值在数组中出现 至少两次 ,返回true
;如果数组中每个元素互不相同,返回false
。- 1)对数组排序
- 2) 遍历数组,同时对比前后数据
#include<iostream> #include<vector>// vector容器头文件 #include<algorithm>// sort排序头文件 using namespace std; bool fun(vector<int>& nums) { sort(nums.begin(), nums.end());// 使数组有序,方便下一步前后遍历对比 int n = int(nums.size());// 强转一下(编译器会提示“可能丢失数据”) for (int i = 0; i < n - 1; i++) {// i < n - 1 防止[i + 1]数组越界 if (nums[i] == nums[i + 1]) { return true;// 前后两个数据相等则返回true } } return false;// 一直遍历到最后则说明每个元素互不相同,返回false } int main() { int n; vector<int> nums; cin >> n; for (int i = 0; i < n; i++) { int x; cin >> x; nums.push_back(x);// nums中插入数据 } cout << fun(nums) << endl; /* for (vector<int>::iterator it = nums.begin(); it != nums.end(); it++) {// 迭代器遍历vector cout << *it << " "; } */ return 0; } // 测试用例 /* input: 5 5 3 3 2 1 output: 1 */
2、最大连续子数组和(贪心+分治)
-
给你一个整数数组
nums
,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4] 输出:6 解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
- 贪心算法
- 1)准备两个标记cur_sum,max_sum,初始化值为数组第一个元素
- cur_sum:当前序列和,如果当前序列和小于0,则舍弃(置0),大于0则赋值cur_sum为当前元素值nums[i]+cur_sum,
- max_sum:最大序列和,每次比较max_sum和cur_sum,max_sum赋值为两者较大值
- 2)从数组下标为1开始遍历数组,执行上述操作
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int fun(vector<int>& nums) {
if (nums.empty()) return 0;// 如果数组无元素 返回值0
int cur_sum, max_sum;
cur_sum = max_sum = nums[0];
for (int i = 1; i < nums.size(); i++) {
if (cur_sum < 0) cur_sum = 0;
cur_sum = cur_sum + nums[i];
max_sum = max(cur_sum, max_sum);
}
return max_sum;
}
int main() {
int n;
cin >> n;
vector<int> nums;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
nums.push_back(x);
}
cout << fun(nums) << endl;
/*for (vector<int>::iterator it = nums.begin(); it != nums.end(); it++) {
cout << *it << " ";
}*/
return 0;
}
// 测试用例
/*
input:
9
-2 1 -3 4 -1 2 1 -5 4
output:
6
*/
-分治法
- 1)分治:数组分为区间[l,r],在区间中取 m = ⌊(l+r)/2⌋,把区间分为左子区间和右子区间
- 2)合:定义四个变量,放在结构体中
- iSum:表示[l,r]的区间和,即左子区间的iSum+右子区间的iSum
- iSum:表示[l,r]的区间和,即左子区间的iSum+右子区间的iSum
- lSum:表示[l,r]内以l为左端点的最大子段和,可能为左子区间的lSum,或者左子区间的iSum+右子区间的lSum,两者取最大
- rSum:表示[l,r]内以r为右端点的最大子段和,可能为右子区间的lSum,或者右子区间的iSum+左子区间的rSum,两者取最大
- mSum:可能是Max(左子区间的最大和,右子区间的最大和)或者左子区间的rSum+右子区间的lSum,两者取最大
- 3)分:当递归逐层深入直到区间长度缩小为 1 的时候,递归「开始回升」,调用“合”
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct Status {
int lSum, rSum, mSum, iSum;
}fun;
Status pushUp(Status l, Status r) {
Status act; // 定义一个结构体对象
int iSum = l.iSum + r.iSum; //iSum 表示[l, r]的区间和
int lSum = max(l.lSum, l.iSum + r.lSum); //lSum 表示[l, r]内以 l 为左端点的最大子段和
int rSum = max(r.rSum, r.iSum + l.rSum); //rSum 表示[l, r]内以 r 为右端点的最大子段和
int mSum = max(max(l.mSum, r.mSum), l.rSum + r.lSum); //mSum 表示[l, r]内的最大子段和
act.iSum = iSum;
act.lSum = lSum;
act.rSum = rSum;
act.mSum = mSum;
return act;
}
Status get(vector<int>& a, int l, int r) { // get(a, l, r) 表示查询 a 序列 [l,r] 区间内的最大子段和
if (l == r) { // 当区间内元素只有一个元素时,lSum、rSum、iSum、mSum均为此元素
fun.iSum = a[l];
fun.lSum = a[l];
fun.rSum = a[l];
fun.mSum = a[l];
return fun;
}
// 否则,缩小区间
int m = (l + r) / 2;
Status lSub = get(a, l, m);
Status rSub = get(a, m + 1, r);
return pushUp(lSub, rSub);
}
int main() {
int n;
cin >> n;
vector<int> nums;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
nums.push_back(x);
}
cout << get(nums, 0, nums.size() - 1).mSum << endl;
/*for (vector<int>::iterator it = nums.begin(); it != nums.end(); it++) {
cout << *it << " ";
}*/
return 0;
}
// 测试用例
/*
input:
9
-2 1 -3 4 -1 2 1 -5 4
output:
6
*/