目录
这题不清楚暴力是否能过,要是每一次都计算一遍和肯定很浪费计算资源。
我们可以把前缀和计算一遍,再把后缀和计算一遍,这个复杂度是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;
- }
- };
这题乍一看是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;
- }
- };
这题的关键在于我们需要从右向左看,但是单向链表逆序遍历又比较麻烦,所以我们先遍历一遍链表,将所有链表的值保存下来。
然后从右往左遍历数组,只保留下右侧没有比其更大的节点。
最后再新建一个链表,当然你也可以在原来的链表上删除,因为第二步得出了需要保存节点的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;
- }
- };
这题我没来得及写完,我当时的思路很简单:回溯得到所有子数组,然后遍历一遍得到符合条件的数量。
但是连续子数组用回溯不好写,如果用暴力双循环的话,复杂度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;
- }
- };
再加油吧!