目录
前缀数组:6245. 找出中枢整数
这题不清楚暴力是否能过,要是每一次都计算一遍和肯定很浪费计算资源。
我们可以把前缀和计算一遍,再把后缀和计算一遍,这个复杂度是O(N+N)
然后再把遍历一遍,返回前缀数组和后缀数组相等的即可。
class Solution {
public:
int pivotInteger(int n) {
int ans = -1;
int sum = 0;
int presum[n+1];
for (int i = 1; i <= n; i++) {
sum += i;
presum[i] = sum;
}
int temp = 0;
int backsum[n+1];
sum = 0;
for (int i = n; i>=1; i--) {
sum += i;
backsum[i] = sum;
}
for (int i = 1; i <= n; i++) {
if (presum[i] == backsum[i]) {
return i;
}
}
return ans;
}
};
双指针:6246. 追加字符以获得子序列
这题乍一看是KMP,但是KMP是要把模板数组全部匹配,这题不用这么麻烦。直接双指针遍历,让指向字符串s的指针走的快,指向字符串t的指针走得慢,tp就是两个字符串相互重复的最大部分。
class Solution {
public:
int appendCharacters(string s, string t) {
int ts = 0;
int tp = 0;
while (ts <= s.size() && tp <= s.size()) {
if (s[ts] == t[tp]) {
ts ++;
tp ++;
} else {
ts ++;
}
}
if (t.size() - tp == -1) {
return 0;
}
return t.size() - tp;
}
};
数组模拟:6247. 从链表中移除节点
这题的关键在于我们需要从右向左看,但是单向链表逆序遍历又比较麻烦,所以我们先遍历一遍链表,将所有链表的值保存下来。
然后从右往左遍历数组,只保留下右侧没有比其更大的节点。
最后再新建一个链表,当然你也可以在原来的链表上删除,因为第二步得出了需要保存节点的val。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeNodes(ListNode* head) {
if (head->next == nullptr) {
return head;
}
vector<int> v;
while (head) {
v.push_back(head->val);
head = head->next;
}
int backmax[v.size()];
int maxnum = v[v.size() - 1];
backmax[v.size() - 1] = maxnum;
for (int i = v.size() - 2; i >= 0; i--) {
if (v[i] < maxnum) {
backmax[i] = maxnum;
} else {
backmax[i] = v[i];
maxnum = v[i];
}
}
vector<int> last;
for (int i = 0; i < v.size(); i++) {
if (v[i] >= backmax[i]) {
last.push_back(v[i]);
}
}
ListNode* dummy = new ListNode(-1);
ListNode* cur = dummy;
for (int i = 0; i < last.size(); i++) {
ListNode* temp = new ListNode(last[i]);
cur->next = temp;
cur = cur->next;
}
return dummy->next;
}
};
中心扩散:6248. 统计中位数为 K 的子数组
这题我没来得及写完,我当时的思路很简单:回溯得到所有子数组,然后遍历一遍得到符合条件的数量。
但是连续子数组用回溯不好写,如果用暴力双循环的话,复杂度O(N*N),这样也过不了。
后来看到到来用中心扩散过了,笑死:力扣
class Solution {
public:
int countSubarrays(vector<int>& nums, int k) {
int n=nums.size(),idx=-1;
for(int i=0;i<n;i++)
{
if(nums[i]==k)idx=i;
}
if(idx==-1)return 0;
int cnt=0,sum=0;
unordered_map<int,int>left;
left[0]=1;
for(int i=idx-1;i>=0;i--)
{
if(nums[i]<k)sum--;
else sum++;
left[sum]++;
}
cnt+=left[0];
cnt+=left[1];
sum=0;
for(int i=idx+1;i<n;i++)
{
if(nums[i]<k)sum--;
else sum++;
cnt+=left[-1*sum];
cnt+=left[1-sum];
}
return cnt;
}
};
再加油吧!