leetcode解题思路分析(一百三十五)1144 - 1150 题

文章探讨了如何通过减少元素值的操作将数组转化为锯齿状,并提供了相关代码实现。同时介绍了快照数组的数据结构,用于存储不同时间点的数组状态。还涉及字符串处理问题,如单字符重复子串和最长段式回文分解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1144.递减元素使数组呈锯齿状
给你一个整数数组 nums,每次 操作 会从中选择一个元素并 将该元素的值减少 1。
如果符合下列情况之一,则数组 A 就是 锯齿数组:
每个偶数索引对应的元素都大于相邻的元素,即 A[0] > A[1] < A[2] > A[3] < A[4] > …
或者,每个奇数索引对应的元素都大于相邻的元素,即 A[0] < A[1] > A[2] < A[3] > A[4] < …
返回将数组 nums 转换为锯齿数组所需的最小操作次数。

遍历一遍分别讨论二者即可

class Solution {
public:
    int movesToMakeZigzag(vector<int>& nums) {
        int n = nums.size();
        int ans1=0, ans2=0;
        for (int i=0; i<n; ++i) {
            //把该位置变成比前一个小需要d1步
            int d1 = (i>0 && nums[i]>=nums[i-1]) ? (nums[i] - nums[i-1] + 1) : 0;
            //把该位置变成比后一个小需要d2步
            int d2 = (i<n-1 && nums[i]>=nums[i+1]) ? (nums[i] - nums[i+1] + 1) : 0;
            //取max就把该位置凹下去
            //按奇偶累加
            if (i%2) {
                ans1 += max(d1, d2);
            } else {
                ans2 += max(d1, d2);
            }
        }
        //按奇偶位置凹下去需要比较少的那个方案
        return min(ans1, ans2);
    }
};
  1. 快照数组
    实现支持下列接口的「快照数组」- SnapshotArray

定义一个当前数组,一个存放snap的数组, 每次snap的时候,将snap_id++当前数字存入snap的数组中.
然后根据snap_id和index获取数组元素.

class SnapshotArray {
public:
    SnapshotArray(int length):cur_arr(length,0) {
        snap_count=0;
    }
    
    void set(int index, int val) {
        cur_arr[index]=val;
    }
    
    int snap() {
        snap_count++;
        snap_arr.push_back(cur_arr);
        return snap_count-1;
    }
    
    int get(int index, int snap_id) {
        return snap_arr[snap_id][index];
    }
    vector<int> cur_arr;
    vector<vector<int>> snap_arr;
    int snap_count;
};

/**
 * Your SnapshotArray object will be instantiated and called as such:
 * SnapshotArray* obj = new SnapshotArray(length);
 * obj->set(index,val);
 * int param_2 = obj->snap();
 * int param_3 = obj->get(index,snap_id);
 */

  1. 段式回文
    你会得到一个字符串 text 。你应该把它分成 k 个子字符串 (subtext1, subtext2,…, subtextk).
    返回k可能最大值。
class Solution {
public:
    int longestDecomposition(string text) {
        int n = text.size();        
        if(text.size() == 0){
            return 0;
        }
        for(int i = 1;i <= n/2; ++i){
           if(text.substr(0,i) == text.substr(n-i,i)){
               return 2 + longestDecomposition(text.substr(i,n-2*i));
           }
        }
        
        return 1;
    }
};


  1. 文章浏览1
    请编写一条 SQL 查询以找出所有浏览过自己文章的作者,结果按照 id 升序排列。
# Write your MySQL query statement below
SELECT DISTINCT author_id AS id
FROM  Views
WHERE author_id = viewer_id
ORDER BY author_id


  1. 一年中的第几天
    给你一个字符串 date ,按 YYYY-MM-DD 格式表示一个 现行公元纪年法 日期。返回该日期是当年的第几天。

直接计算就完事了

class Solution {
public:
    int dayOfYear(string date) {
        int year = stoi(date.substr(0, 4));
        int month = stoi(date.substr(5, 2));
        int day = stoi(date.substr(8, 2));

        int amount[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
            ++amount[1];
        }

        int ans = 0;
        for (int i = 0; i < month - 1; ++i) {
            ans += amount[i];
        }
        return ans + day;
    }
};

  1. 单字符重复子串的最大长度
    如果字符串中的所有字符都相同,那么这个字符串是单字符重复的字符串。给你一个字符串 text,你只能交换其中两个字符一次或者什么都不做,然后得到一些单字符重复的子串。返回其中最长的子串的长度。

滑动查找

class Solution {
public:
    int maxRepOpt1(string text) {
        vector<int> cnt(26);
        int ans = 0;
        
        for (char ch : text)
            cnt[ch - 'a'] += 1;
        
        for (int i = 0; i < text.length(); ) {
            int leng = 0;
            while (i + leng < text.length() && text[i + leng] == text[i])
                leng += 1;
            
            int j = i + leng + 1;
            int w = 0;
            while (j + w < text.length() && text[j + w] == text[i])
                w += 1;
            
            ans = max(ans, min(w + leng + 1, cnt[text[i] - 'a']));
            i += leng;
        }
        return ans;
    }
};


  1. 子数组中占绝大多数的元素
    设计一个数据结构,有效地找到给定子数组的 多数元素 。

线段树

class MajorityChecker {
    struct node
    {
        int x,y;
        node operator+(const node& b)const
        {
            node t;
            if(x==b.x)
            {
                t.x=x;
                t.y=y+b.y;
            }
            else if(y<b.y)
            {
                t.x=b.x;
                t.y=b.y-y;
            }
            else
            {
                t.x=x;
                t.y=y-b.y;
            }
            return t;
        }
    }t[65536];
    int n,a[20005];
    vector<int> s[20005];
    void build(int R,int l,int r)
    {
        if(l==r)
        {
            t[R].x=a[l];
            t[R].y=1;
            return;
        }
        int mid=l+r>>1;
        build(R<<1,l,mid);
        build(R<<1|1,mid+1,r);
        t[R]=t[R<<1]+t[R<<1|1];
    }
    node ask(int R,int l,int r,int l1,int r1)
    {
        if(l1==l&&r==r1)return t[R];
        int mid=l+r>>1;
        if(r1<=mid)return ask(R<<1,l,mid,l1,r1);
        if(l1>mid)return ask(R<<1|1,mid+1,r,l1,r1);
        return ask(R<<1,l,mid,l1,mid)+ask(R<<1|1,mid+1,r,mid+1,r1);
    }
public:
    MajorityChecker(vector<int>& arr) {
        n=arr.size();
        int i;
        for(i=0;i<n;i++)s[a[i]=arr[i]].push_back(i);
        build(1,0,n-1);
    }
    
    int query(int left, int right, int threshold) {
        int ans=ask(1,0,n-1,left,right).x;
        if(upper_bound(s[ans].begin(),s[ans].end(),right)-lower_bound(s[ans].begin(),s[ans].end(),left)<threshold)ans=-1;
        return ans;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ch_ty

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值