力扣周赛392复盘

news2024/11/26 4:45:27

在这里插入图片描述

3105. 最长的严格递增或递减子数组

题目

给你一个整数数组 nums 。
返回数组 nums 中 严格递增严格递减 的最长非空子数组的长度。

思考:

返回什么:返回最长非空子数组的长度。return max(decs_len,incs_len);
但实际上我们只需要用一个变量ans就可以,不用使用decs_len,incs_len。如ans=(ans,cur_len);cur_len=right-left+1(这个是否要+1可以让left=right=0时判断)

方法一:暴力破解:
class Solution {
public:
    int longestMonotonicSubarray(vector<int>& nums) {
        int n = nums.size();
        int ans = 1;
        for (int i = 0; i < n; i++) {
            for (int j = i+1;j < n; j++) {
                if(nums[j]<=nums[j-1]){//不严格递增
                    break;
                }//[i,j]严格递增
                ans=max(j-i+1,ans);
            }
            for (int k= i+1; k< n; k++) {
                if(nums[k]>=nums[k-1]){//不严格递减
                    break;
                }
                ans=max(k-i+1,ans);
            }
        }
        return ans;
    }
};

时间复杂度0(n²)

方法二:分组循环:

如例子nums = [1,2,3,4,3,3,2] ;

  • 1.如果我们确定 【1,2,3,4】为递增数列,那么我们可以确定 【2,3,4】、【3,4】、【4】均为递增数列。 即开始点为left,结束点为right时,我们可以确定right-left+1个递增数列(3-0+1=4)
  • 但需要注意,实际上我们结束点是第一个不满足的点,所以数量为right-left。
  • 2.如果我们确定【1,2,3,4,3】不是递增数列,那我们要再从那个节点开始遍历呢?
  • * 第一想法从 3开始遍历 即直接从上一个right++完之后遍历。但是捏,【4,3】不是递增数列说明什么说明,说明他是递减数列,所以我们要从4开始遍历,我们上一个right++(此时到3)完之后-1再遍历。
  • 3.那我们怎么判断递增还是递减呢?可以用一个bool类型的变量 inc(1=增,0=减)

整体流程:

用right指针 遍历数组,如果连续两个元素重复,right后移,跳出循环,(再来一次判断)直到不相等。用left记录每次的起始点,right记录每次的结束点。如果数组严格单调且right不越界,right++。一次遍历之后更新ans,right从第一个不满足的点变为上一个节点

代码如下:

class Solution {
public:
    int longestMonotonicSubarray(vector<int>& nums) {
        int n = nums.size();
        int ans = 1; // 初始化结果为1,因为最短的单调子数组长度至少为1
        int left = 0; // 左边界初始位置
        int right = 0; // 右边界初始位置
        while (right < n - 1) { // 遍历数组,注意右边界不超过数组末尾的前一个元素
            if (nums[right] == nums[right + 1]){
                right++;
                continue;
            } // 如果右边界和下一个元素相同,继续向右移动右边界
            left = right; // 更新左边界为当前右边界位置,记录这一组的开始位置
            bool inc = nums[right + 1] - nums[right] > 0; // 判断单调性
            right++; // 移动右边界到下一个位置
            while (right < n && (nums[right] - nums[right - 1] > 0) == inc&&nums[right] != nums[right - 1] ) // 向右移动右边界直到不满足单调性为止
                right++;
            ans = max(ans, right - left); // 更新结果,当前子数组长度为右边界减去左边界
            right-=1;
        }
        return ans;
    }
};

时间复杂度:O(n)。时间复杂度乍一看是 O(n^2),但注意变量 i 减少的次数是 O(n)其它情况一直在增加,由于 i最大是 n,所以增加的次数是 O(n)所以二重循环总共循环 O(n) 次,时间复杂度是 O(n) 的。
空间复杂度:O(1)。仅用到若干额外变量。

分组循环使用条件: 如果按照题意,可以把数组分成若干段满足要求的子数组,每一段之间没有交集。

3106. 满足距离约束且字典序最小的字符串

题目

给你一个字符串 s 和一个整数 k 。

定义函数 distance(s1, s2) ,用于衡量两个长度为 n 的字符串 s1 和 s2 之间的距离,即:

字符 ‘a’ 到 ‘z’ 按 循环 顺序排列,对于区间 [0, n - 1] 中的 i ,计算所有【 s1[i] 和 s2[i] 之间 最小距离】的 和 。

例如,distance(“ab”, “cd”) = 4 ,且 distance(“a”, “z”) = 1 。
你可以对字符串 s 执行 任意次 操作。在每次操作中,可以将 s 中的一个字母 改变 为 任意 其他小写英文字母。
返回一个字符串,表示在执行一些操作后你可以得到的 字典序最小 的字符串 t ,且满足 distance(s, t) <= k

思路

  1. distance(“a”, “z”) = 1 这是因为字符 ‘a’ 到 ‘z’ 按 循环 顺序排列,Z的后面就是A。
    所以距离distance_a(从当前元素x到a的距离)=min(x-‘a’,‘z’-x+1);
  2. 要认清一个问题 a<b;abc<bbc;即越前面的元素越靠近a字典序越小
  3. 使用贪心算法,在k次内尽可能多的让元素变为a;当k不够变成A的时候,让元素直接-k变小即可。

代码:

class Solution {
public:
    string getSmallestString(string s, int k) {
        int n=s.size();
        int i=0;
        while(k>=0){
            if(i==n) break;
            char x=s[i];
            int dis=min(x-'a','z'-x+1);
            if(k>=dis){
                s[i++]='a';
                k-=dis;
            }
            else{
                s[i++]-=k;
                break;
            }
        }
        return s;

    }
};

时间复杂度:O(n),空间复杂度:O(1), C++ 可以原地修改字符串。

class Solution:
    def getSmallestString(self, s: str, k: int) -> str:
        s=list(s)
        for i,x in enumerate(map(ord,s)):
            dis=min(x-ord('a'),ord('z')-x+1)
            if k>=dis:
                s[i]='a'
                k-=dis
            else:
                s[i]=chr(x-k)
                break
        return''.join(s)

字符串转换为了列表 s,这会占用额外的空间。在 Python 中,字符串是不可变的,因此将其转换为列表以便修改会增加空间复杂度。将其转换为列表需要额外的 O(n) 空间。
时间复杂度:O(n),空间复杂度:O(n)

3107. 使数组中位数等于 K 的最少操作数

题目

给你一个整数数组 nums 和一个非负整数 k 。一次操作中,你可以选择任一元素 加 1 或者减 1 。
请你返回将 nums 中位数 变为 k 所需要的 最少 操作次数。
一个数组的中位数指的是数组按非递减顺序排序后最中间的元素。如果数组长度为偶数,我们选择中间两个数的较大值为中位数。

示例

示例 1:
输入:nums = [2,5,6,8,5], k = 4
输出:2
解释:我们将 nums[1] 和 nums[4] 减 1 得到 [2, 4, 6, 8, 4] 。现在数组的中位数等于 k 。

示例 2:
输入:nums = [2,5,6,8,5], k = 7
输出:3
解释:我们将 nums[1] 增加 1 两次,并且将 nums[2] 增加 1 一次,得到 [2, 7, 7, 8, 5] 。

思考

  1. 这道题的中位数是什么,定义方式–》看加粗字体。由此我们能得出来,中位数的下标为n/2(数组排序后);例如:【0,1,2】中位数下表为3/2=1;【0,1,2,3】中位数下表为4/2=2.(中间较大的那个)。
  2. 示例一:nums = [2,5,6,8,5]–》sort后为 [2,5,5,6,8] 那么我们怎么让中位数=4呢?其实不难想到需要先将中间的数X变为4,但是这样子数组【5,4】还得再次变换?不用那么麻烦,直接将【5,4】中的5也变成4即可。如此就有数组[2,4,4,6,8] 中位数为4(而在此期间,6,8我们没有进行处理这是因为中间的数X>4,那么排序后 后面的数也必然大于4,不用进行操作。);示例二同样。
  3. 经过示例一二:我们可以得出结论:我们只需要将数组排序,然后让中间的数X变为k,再将X的前小于或后大于的数进行变动。

代码

class Solution {
public:
    long long minOperationsToMakeMedianK(vector<int>& nums, int k) {
        long long ans = 0;//切记设置成龙龙
        sort(nums.begin(), nums.end());
        long long mid = nums.size() / 2;
        if (nums[mid] == k)
            return 0;
        if (nums[mid] > k) {
            for (long long i = mid; i >= 0; i--) {//切记i==0!!!
                if (nums[i] > k)
                    ans += nums[i] - k;
                else
                    break;//一个小于前面的都小
            }
        } // 前面的可能也大于
        if (nums[mid] < k) {
            for (long long i = mid; i < nums.size(); i++) {
                if (nums[i] < k)
                    ans += k - nums[i];
                else
                    break;
            }
        }
        return ans;
    }
};

3108. 带权图里旅途的最小代价

题目

给你一个 n 个节点的带权无向图,节点编号为 0 到 n - 1 。
给你一个整数 n 和一个数组 edges ,其中 edges[i] = [ui, vi, wi] 表示节点 ui 和 vi 之间有一条权值为 wi 的无向边。
在图中,一趟旅途包含一系列节点和边。旅途开始和结束点都是图中的节点,且图中存在连接旅途中相邻节点的边。注意,一趟旅途可能访问同一条边或者同一个节点多次。
如果旅开始于节点 u ,结束于节点 v ,我们定义这一趟旅途的 代价 是经过的边权按位与 AND 的结果。换句话说,如果经过的边对应的边权为 w0, w1, w2, …, wk ,那么代价为w0 & w1 & w2 & … & wk ,其中 & 表示按位与 AND 操作。
给你一个二维数组 query ,其中 query[i] = [si, ti] 。对于每一个查询,你需要找出从节点开始 si ,在节点 ti 处结束的旅途的最小代价。如果不存在这样的旅途,答案为 -1 。
返回数组 answer ,其中 answer[i] 表示对于查询 i 的 最小 旅途代价。

示例

示例 1:

输入:n = 5, edges = [[0,1,7],[1,3,7],[1,2,1]], query = [[0,3],[3,4]]

输出:[1,-1]

解释:
在这里插入图片描述

第一个查询想要得到代价为 1 的旅途,我们依次访问:0->1(边权为 7 )1->2 (边权为 1 )2->1(边权为 1 )1->3 (边权为 7 )。

第二个查询中,无法从节点 3 到节点 4 ,所以答案为 -1 。

思路:

  1. 按位与 AND:按位与操作:1&1=0,1&0=0;0&0=0;他有一条性质是数 越与越小
    例如示例一:7=111 1=001 7&1=111&001=001;
    =按位与运算的初始值可以用-1 原因:-1的补码是1111111。
  2. 本题可以分为三大类情况:(起始点记为start,结束点记为finish)
    1. start==finish,路径代价为0
    2. start,finish 两个点不联通 路径代价为-1
    3. start,finish 两个点联通 ,路径代价为 当前图的所有路径相与值。
  3. 如此,大体思路即为,建立两个数组。一个数组存放当前点所在图的编号;另一个数组cc_and存放当前图的所有路径相与值,结合三种情况,求出最终结果。

代码:

class Solution {
    vector<vector<pair<int, int>>> g;
    vector<int> cc_and, ids;

    int dfs(int x) {
        ids[x] = cc_and.size(); // 记录每个点所在连通块的编号
        int and_ = -1;
        for (auto &[y, w]: g[x]) {
            and_ &= w;
            if (ids[y] < 0) { // 没有访问过
                and_ &= dfs(y);
            }
        }
        return and_;
    }

public:
    vector<int> minimumCost(int n, vector<vector<int>> &edges, vector<vector<int>> &query) {
        g.resize(n);
        for (auto &e: edges) {
            int x = e[0], y = e[1], w = e[2];
            g[x].emplace_back(y, w);
            g[y].emplace_back(x, w);
        }

        ids.resize(n, -1); // 记录每个点所在连通块的编号
        for (int i = 0; i < n; i++) {
            if (ids[i] < 0) { // 没有访问过
                cc_and.push_back(dfs(i)); // 记录每个连通块的边权的 AND
            }
        }

        vector<int> ans;
        ans.reserve(query.size()); // 预分配空间
        for (auto &q: query) {
            int s = q[0], t = q[1];
            ans.push_back(ids[s] != ids[t] ? -1 : cc_and[ids[s]]);
        }
        return ans;
    }
};

时间复杂度:O(n+m+q) 的长度。
空间复杂度:O(n+m)。返回值不计入。

以上over 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1600168.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【优质书籍推荐】AI赋能100%提高项目管理效率

大家好&#xff0c;我是爱编程的喵喵。双985硕士毕业&#xff0c;现担任全栈工程师一职&#xff0c;热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。…

Vision GNN: An Image is Worth Graph of Nodes

感受野&#xff1a;在卷积神经网络中,感受野(Receptive Field)是指特征图上的某个点能看到的输入图像的区域,即特征图上的点是由输入图像中感受野大小区域的计算得到的。 感受野并非越大越好&#xff0c;反而可能因为过大而过于发散梯度下降&#xff08;Gradient Descent GD&am…

在linux系统中启动pycharm

1.找到pycharm的安装路径&#xff0c;一般在下载文件夹中 2.进入pycharm的安装路径&#xff0c;进入bin目录 3.右击&#xff0c;打开终端&#xff0c;输入./pycharm.sh

民航电子数据库:[E14024]事务内变更操作次数超过最大许可值10000,可通过系统参数max_trans_modify适当调整限制

目录 一、场景二、异常情况三、原因四、排查五、解决 一、场景 1、对接民航电子数据 2、执行delete语句时报错 二、异常情况 三、原因 通过报错信息就可以看出&#xff0c;是系统参数max_trans_modify配置导致 当删除的数据量 > max_trans_modify时&#xff0c;删除就会…

【LeetCode每日一题】924. 尽量减少恶意软件的传播(并查集)

文章目录 [924. 尽量减少恶意软件的传播](https://leetcode.cn/problems/minimize-malware-spread/)思路&#xff1a;并查集代码&#xff1a; 924. 尽量减少恶意软件的传播 思路&#xff1a;并查集 构建并查集&#xff1a;首先&#xff0c;代码创建了一个 UnionFind 类来维护节…

AIGC教育行业全景报告:AI助教和家教成真,学习机迎来新机遇

原文&#xff1a;AIGC教育行业全景报告&#xff1a;AI助教和家教成真&#xff0c;学习机迎来新机遇 - AI新智界 图片来源&#xff1a;由无界AI生成 经过一年的快速迭代&#xff0c;业内对于生成式AI将会率先落地于哪些行业已经有了答案。 教育领域&#xff0c;不仅被OpenAI列…

leetcode1448.统计二叉树中的好节点数目

1. 题目描述 题目链接 2. 解题思路 首先看一下题目的“核心”&#xff0c;什么是好节点&#xff1a;从根到该节点 X 所经过的节点中&#xff0c;没有任何节点的值大于 X 的值。也就是说&#xff0c;我们只要知道了从根节点到该节点的所有的值&#xff0c;就可以判断该节点是…

【代理模式】静态代理-简单例子

在Java中&#xff0c;静态代理是一种设计模式&#xff0c;它涉及到为一个对象提供一个代理以控制对这个对象的访问。静态代理在编译时就已经确定&#xff0c;代理类和被代理类会实现相同的接口或者是代理类继承被代理类。客户端通过代理类来访问&#xff08;调用&#xff09;被…

iOS依赖库版本一致性检测:确保应用兼容性

一、背景 在 iOS 应用开发的世界里&#xff0c;每次 Xcode 更新都带来了新的特性和挑战。最近的 Xcode 15 更新不例外&#xff0c;这次升级引入了对 SwiftUI 的自动强依赖。SwiftUI最低是从 iOS 13 开始支持。 这一变化也带来了潜在的兼容性问题。如果您的项目在升级到 Xcode…

《大话数据结构》02 算法

算法是解决特定问题求解步骤的描述&#xff0c;在计算机中表现为指令的有限序列&#xff0c;并且每条指令表示一个或多个操作。 1. 两种算法的比较 大家都已经学过一门计算机语言&#xff0c;不管学的是哪一种&#xff0c;学得好不好&#xff0c;好歹是可以写点小程序了。现在…

为什么你不用懒人建站工具?套用这四个wordpress主题模板,1小时轻松搭建网站

懒人建站工具&#xff0c;凭借简单易用、快速上手和个性化定制的特点&#xff0c;为不熟悉代码和程序的人提供了搭建美观实用网站的便捷途径。无需专业的前端开发知识&#xff0c;无需雇佣专业开发人员&#xff0c;用户便能轻松实现网站搭建&#xff0c;满足个人或企业需求。懒…

【可实战】测试体系与测试方案设计(业务按公司实际情况,技术可参考通用测试方案)

一、如果我们要测试一个系统&#xff0c;首先我们要了解被测系统的架构 &#xff08;一&#xff09;业务架构-从需求里面去了解&#xff08;角色和行为&#xff09;&#xff1a; 业务模型分析&#xff08;是一个电商&#xff0c;还是一个企业的crm&#xff0c;还是一个网站&a…

高等数学——一文搞定二重积分

文章目录 二重积分的基本概念二重积分的性质累次积分计算二重积分的方法和技巧描点画图法对称性利用函数的奇偶性变量的轮换对称性 积分次序的选择积分区域的确认先看变量和先积变量基本原则穿线法确定先积变量的曲线范围 常见的曲线经典题目 二重积分的基本概念 定义&#xf…

ChatGPT 可以预测未来吗?

推荐 4月13日的一篇有趣的 paper&#xff0c;特来分享。 &#x1f449; 当前的大型语言模型&#xff08;LLMs&#xff09;具有强大的数据合成和推理能力&#xff0c;但它们在直接预测尚未发生事件的准确性上常常受到限制。传统的预测方法依赖于直接询问模型关于未来的问题。 …

测出Bug就完了?从4个方面教你Bug根因分析

01 现状及场景 &#x1f3af; 1.缺失bug根因分析环节 工作10年&#xff0c;虽然不是一线城市&#xff0c;也经历过几家公司&#xff0c;规模大的、规模小的都有&#xff0c;针对于测试行业很少有Bug根因环节&#xff0c;主流程基本上都是测试提交bug-开发修改-测试验证-发送报…

Spring学习(二)

图解&#xff1a; 2.核心容器总结 2.2.1 容器相关 BeanFactory是IoC容器的顶层接口&#xff0c;初始化BeanFactory对象时&#xff0c;加载的bean延迟加载 ApplicationContext接口是Spring容器的核心接口&#xff0c;初始化时bean立即加载 ApplicationContext接口提供基础的be…

为什么科拓停车选择OceanBase来构建智慧停车SaaS应用

本文来自OceanBase的客户——拓客停车的实践分享 科拓停车简介与业务背景 作为智慧停车行业的佼佼者&#xff0c;科拓停车致力于提供全方位的智慧停车解决方案。服务涵盖车场运营管理、互联网智慧停车平台以及停车场增值服务等。通过不断研发创新&#xff0c;打造出了多样化的…

C++命名空间在内部声明函数,在外部定义函数

C命名空间在内部声明函数&#xff0c;在外部定义函数 #include <iostream> namespace A {int a;void func(); } void A::func() {std::cout << "Hello World!" << std::endl; } void main() {A::func(); }实际运行的代码和结果图如下&#xff1a;…

十大排序——10.基数排序

下面我们来看一下基数排序 目录 1.介绍 2.代码实现 3.总结与思考 1.介绍 基数排序&#xff08;Radix sort&#xff09;是一种非比较型整数排序算法 基本思想&#xff1a; 它的原理是将整数按位数切割成不同的数字&#xff0c;然后按每个位数分别比较。基数排序的方式可以…

「51媒体」如何有效进行媒体邀约,提升宣传传播效果?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 进行有效的媒体邀约&#xff0c;提升宣传传播效果的关键在于策略性和专业性。以下是具体的做法&#xff1a; 明确目标&#xff1a;要确立清晰的品牌推广目标和策略&#xff0c;包括确定目…