前缀和代码分析:
第一步:预处理
function initPrefixSum(a, sum, size)
sum[0] = a[0];
for i -> (1, size-1)
sum[i] = sum[i-1] + a[i];
第二步:查询
function getPartialSum(sum, l, r)
if l==0
return sum[r]
return sum[r] - sum[l-1]
第一次-内存优化:
function initPrefixSum(a, size)
for i -> (1, size-1)
a[i] = a[i-1] + a[i];
代码练习 1 对应力扣 一维数组的动态和,代码见下
class Solution {
public:
vector<int> runningSum(vector<int>& nums) {
vector<int> runningSum;
runningSum.push_back(nums[0]);
for(int i=1; i<nums.size(); ++i){
int x = runningSum[i-1] + nums[i];
runningSum.push_back(x);
}
return runningSum;
}
};
代码练习 2 对应力扣 找到数组的中间位置 代码见下
class Solution {
public:
int findMiddleIndex(vector<int>& nums) {
int sum[210];
int n = nums.size();
sum[0] = nums[0];
for(int i = 1; i < n; ++i){
sum[i] = sum[i-1] + nums[i];
}
for(int i = 0; i < nums.size(); ++i){
int middleIndex = i;
int a = 0, b = 0;
if(middleIndex)
a = sum[middleIndex - 1];
b = sum[n-1] - sum[middleIndex];
if(a == b){
return middleIndex;
}
}
return -1;
}
};
代码练习,对应力扣,寻找数组的中心下标,代码见下
class Solution {
public:
int pivotIndex(vector<int>& nums) {
int n = nums.size();
for(int i = 1; i < n; ++i){
nums[i] += nums[i-1];
}
for(int i = 0; i < nums.size(); ++i){
int middleIndex = i;
int a = 0, b = 0;
if(middleIndex)
a = nums[middleIndex - 1];
b = nums[n-1] - nums[middleIndex];
if(a == b){
return middleIndex;
}
}
return -1;
}
};
双指针:
快慢指针:就是两个指针,从同一侧开始遍历序列,移动步长一个快一个慢。常见应用有,链表判环,获取链表中间结点,删除有序数组重复项。
对撞指针:是指两个指针,分别指向序列的第一个元素和最后一个元素,然后指针相向移动,一个指针递增一个指针递减,直到两个指针值相撞或者满足其他特殊条件为止。常见应用有,两数之和,回文串判定,字符串的反转等等
分离双指针:两个指针分别属于不同的数组(或链表),两个指针分别在两个数组(或链表)中移动,从而解决相关算法问题,常见应用,有序数组合并,归并排序中的合并部分,对两数组求交集和并集。这个的优点便可以降低时间复杂度。
代码分析:
求链表的中点
function middleNode(head)
slow=fast=head
while fast and fast.next
slow = slow.next
fast = fast.next.next
return slow
数组中移除元素
function removeElement(arr, n, val)
l = 0
r = n - 1
while(l <= r)
if(arr[l] == val)
arr[l] = arr[r]
r -= 1
else
l += 1
return l
代码练习,对应蓝桥云课 回文判定 代码见下
#include <iostream>
#include<string>
using namespace std;
int main()
{
string s;
cin >> s;
int i = 0;
int j = s.size() - 1;
while(i < j){
if(s[i] != s[j]){
break;
}
i += 1;
j -= 1;
}
if(i >= j){
cout << 'Y' << endl;
}else{
cout << 'N' << endl;
}
// 请在此输入您的代码
return 0;
}
代码练习,对应蓝桥云课 反转字符串中的字符,代码见下
#include <iostream>
#include <string.h>
using namespace std;
char s[1000];
int main()
{
cin.getline(s, 101, '\n');
int i = 0;
int j = strlen(s) - 1;
while(i < j){
swap(s[i], s[j]);
i += 1;
j -= 1;
}
cout << s << endl;
// 请在此输入您的代码
return 0;
}
代码练习,对应蓝桥云课 等腰三角形 代码见下
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 200001
int A[maxn], B[maxn], C[maxn];
int n;
int main()
{
cin >> n;
for(int i=0; i<n; ++i){
cin >> A[i];
C[i] = 2 * A[i];
}
for(int i=0; i<n; ++i){
cin >> B[i];
}
sort(C, C+n);
sort(B, B+n);
int i=0, j=0, ans=0;
while(i < n && j < n){
if(C[i] > B[j]){
j += 1;
ans += 1;
}
i += 1;
}
cout << ans << endl;
// 请在此输入您的代码
return 0;
}