佳期投资专场——第321场LeetCode周赛题解

Posted 沉迷单车的追风少年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了佳期投资专场——第321场LeetCode周赛题解相关的知识,希望对你有一定的参考价值。

目录

前缀数组:6245. 找出中枢整数

双指针:6246. 追加字符以获得子序列

数组模拟:6247. 从链表中移除节点

中心扩散:6248. 统计中位数为 K 的子数组


前缀数组: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;
    
;

再加油吧!

以上是关于佳期投资专场——第321场LeetCode周赛题解的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 第29场 双周赛 题目4 题解

Leetcode第52场双周赛总结+题解

阿里巴巴专场——第322场周赛题解

LeetCode AutoX 安途智行专场竞赛题解

LeetCode第69场双周赛

Leetcode 第 173 场周赛 题解