第 321 场力扣周赛

第 321 场力扣周赛

T1

求和

class Solution {
public:
    int pivotInteger(int n) {
        int sum=(1+n)*n/2;
        int cnt=0;
        for(int i=1;i<=n;i++){
            cnt+=i;
            if(sum-cnt+i==cnt) return i;
        }
        return -1;
    }
};

T2

逐个按顺序判断t的字符是否在s中,遍历s看能走到t的哪一步。、

class Solution {
public:
    int appendCharacters(string s, string t) {
        int n=s.size(),m=t.size();
        int j=0;
        for(int i=0;i<n;i++){
            if(j<m&&s[i]==t[j]) j++;
        }
        cout<<m-j<<endl;
        return m-j;
    }
};

如果这个题,不是无序,而是判断判断s的字符重组之后添加字符,t是s的子串,就应该使用哈希表。

T3

单调栈+删除链表中的某个节点

/**
 * 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) {
        vector<int> val;
        ListNode* q=head;
        while(q){
            val.push_back(q->val);
            q=q->next;
        }
        int len=val.size();
        vector<int> next(len,0);
        stack<int> st;
        for(int i=val.size()-1;i>=0;i--){
            while(!st.empty()&&st.top()<=val[i]) st.pop();
            if(st.empty()) next[i]=-1;
            else next[i]=st.top();
            st.push(val[i]);
        }
        int index=0;
        q=head;
        while(q){
            if(next[index]!=-1){
                q->val=q->next->val;
                q->next=q->next->next;
            }else{
                q=q->next;
            }
            index++;
        }
        return head;
    }
};

T4

中位数的性质,预处理+桶计数

首先题目条件:

  • 每个数都不相同
  • 中位数一定在1~n中的一个

记k的位置为pos

分两种情况:

  • 对于长度为偶数的中位数,大于k和小于k的个数相差1
  • 对于长度为奇数的中位数,大于k和小于k的个数相等

注意我们只需要差值好像就可以,差值为0和1的。所以我们可以统计pos~i的差值的个数

然后在从左边遍历,同样统计差值,假设差值为c,判断后半段是否有相等的和差值为c和c+1的。

class Solution {
public:
    int countSubarrays(vector<int>& nums, int k) {
        int n=nums.size();
        vector<int> l1(n,0),m1(n,0);
        int pos=-1;// 找k的位置
        for(int i=0;i<n;i++) if(nums[i]==k){
            pos=i;
        }//预处理比k大和比k小的个数
        for(int i=pos-1;i>=0;i--){
            if(nums[i]>k) {
                m1[i]=m1[i+1]+1;
                l1[i]=l1[i+1];
            }
            else {
                m1[i]=m1[i+1];
                l1[i]=l1[i+1]+1;
            }
        }
        for(int i=pos+1;i<n;i++){
            if(nums[i]>k) {
                m1[i]=m1[i-1]+1;
                l1[i]=l1[i-1];
            }
            else {
                m1[i]=m1[i-1];
                l1[i]=l1[i-1]+1;
            }
        }
        int ans=0,j=pos;
        map<int,int> cnt;
        cnt[0]=1;
        for(int i=pos+1;i<n;i++){
            cnt[m1[i]-l1[i]]++;
        }
        ans+=cnt[0]+cnt[1];// 位置在pos的时候,大于k的个数和小于K的个数相等,或者相差1
        for(int i=pos-1;i>=0;i--){
            ans+=cnt[l1[i]-m1[i]];
            ans+=cnt[l1[i]-m1[i]+1];
        }
        return ans;
    }
};

代码写的有点啰嗦,赛时代码,懒得想就多写点。

你可能感兴趣的:(力扣,题解,leetcode,算法,职场和发展)