Letbook Cookbook题单——数组3

news2025/1/17 6:02:15

Letbook Cookbook题单——数组3

48. 旋转图像

难度中等

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

示例 1:

img

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]

示例 2:

img

输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]

提示:

  • n == matrix.length == matrix[i].length
  • 1 <= n <= 20
  • -1000 <= matrix[i][j] <= 1000

先把矩阵主对角线翻折再沿中间翻折

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        for(int i=1;i<matrix.size();i++)
    for(int j=0;j<i;j++ )
    {
        swap(matrix[i][j],matrix[j][i]);
    }
   for(int i=0;i<matrix.size();i++)
       for(int j=0;j<matrix.size()/2;j++)
        {
            swap(matrix[i][matrix.size()-j-1],matrix[i][j]);
        }
    }
};

53. 最大子数组和

难度中等

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 10^4

**进阶:**如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。

这题,我只能说经典中的经典,四种解法

暴力

前缀和预处理,然后枚举每个子数组,超时

class Solution
{
public:
    int maxSubArray(vector<int> &nums)
    {
       vector<int>sum(nums.size()+1);
       for(int i=1;i<=nums.size();i++)
       sum[i]=sum[i-1]+nums[i-1];
       int ans=INT_MIN;
       for(int i=1;i<=nums.size();i++)
       for(int j=i;j<=nums.size();j++)
       ans=max(ans,sum[j]-sum[i-1]);
       return ans;
    }
};

贪心

连续的数组,当前一个子数组和为负数,则显然会丢弃
初始化数组和为0,最大值为第一个元素值
遍历数组,更新数组和,并且更新最大值,当数组和<0,则丢弃数组,数组和置零

class Solution
{
public:
int maxSubArray(vector<int>&nums){
int max=INT_MIN;
int sum=0;
for(int i=0;i<nums.size();i++)
{
    sum+=nums[i];
    if(sum>max)
    max=sum;
    if(sum<0)
    sum=0;
}
return max;
}
};

动态规划

dp[i]代表必然选择第i个元素且以第i个元素为子数组最后一个元素的最大子数组和,那么状态转移方程就是dp[i]=dp[i-1]>=0?dp[i-1]+nums[i]:nums[i],和贪心一样,如果前面出现负数就没必要加进来

class Solution
{
public:
    int maxSubArray(vector<int> &nums)
    {
       vector<int>dp(nums.size()+1);
       int ans=INT_MIN;
       for(int i=1;i<=nums.size();i++)
       {
           if(dp[i-1]>=0)
           dp[i]=dp[i-1]+nums[i-1];
           else
           dp[i]=nums[i-1];
           ans=max(ans,dp[i]);
       }
       return ans;
    }
};

分治法

分治法虽然效率没有前面两者好,但是它的思想极其深刻,详细解释可以参考算法导论

假定我们要寻找子数组nums[low… high]的最大子数组。使用分治技术意味着我们要将子数组划分为两个规模尽量相等的子数组。也就是说,找到子数组的中央位置,比如mid,然后考虑求解两个子数组nums[low. . mid]和 nums[mid+1…high]。如图所示,nums[low. . high]的任何连续子数组nums[i…j]所处的位置必然是以下三种情况之一:

完全位于子数组nums[low. . mid]中,因此low<=i<=mid。

完全位于子数组nums[mid+1…high]中,因此mid<i<=i<=j<=high。

跨越了中点,因此low<=i<=mid<j<=high。

在这里插入图片描述

因此,nums[low… high]的一个最大子数组所处的位置必然是这三种情况之一。实际上,A[low. . high]的一个最大子数组必然是完全位于nums[low. . mid]中、完全位于nums[mid+1…high]中或者跨越中点的所有子数组中和最大者。

**我们可以递归地求解nums[low. . mid]和 nums[mid+1…high]的最大子数组,因为这两个子问题仍是最大子数组问题,只是规模更小。**因此,剩下的全部工作就是寻找跨越中点的最大子数组,然后在三种情况中选取和最大者。

我们可以很容易地在线性时间(相对于子数组 nums[low. . high]的规模)内求出跨越中点的最大子数组。

此问题并非原问题规模更小的实例,因为它加人了限制——求出的子数组必须跨越中点。

如图所示,任何跨越中点的子数组都由两个子数组nums[i…mid]和nums[mid+1…j组成,其中 low≤i≤mid且mid<j≤high。因此,我们只需找出形如nums[i… mid]和 nums[mid+1…j]的最大子数组,然后将其合并即可。

在这里插入图片描述

函数find_max_max接收数组nums和下标low、mid和high为输人,返回一个下标元组划定跨越中点的最大子数组的边界,并返回最大子数组中值的和。

早期刷letcode用c语言写的

double find_max_mid(int *nums,int l,int r,int mid)
{
    double lmax=-1e10,rmax=-1e10,maxl,maxr;
    double sum=0;
    for(int i=mid;i>=l;i--)
    {
        sum+=nums[i];
        if(lmax<sum)
        {
            maxl=i;
            lmax=sum;
        }
    }
    sum=0;
    for(int i=mid+1;i<=r;i++)
    {
        sum+=nums[i];
        if(rmax<sum)
        {
            maxr=i;
            rmax=sum;
        }
    }
    return lmax+rmax;
}
double find_max(int *nums,int l,int r)
{
    if(l==r)
    return nums[l];
    else
    {
        int mid=(l+r)/2;
        double lmax=find_max(nums,l,mid);
        double rmax=find_max(nums,mid+1,r);
        double midmax=find_max_mid(nums,l,r,mid);
        if(lmax>=rmax&&lmax>=midmax)
        return lmax;
        else if(rmax>=lmax&&rmax>=midmax)
        return rmax;
        else
        return midmax;
    }
}
int maxSubArray(int* nums, int numsSize){
return find_max(nums,0,numsSize-1);
}

54. 螺旋矩阵

难度中等

给你一个 mn 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例 2:

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 10
  • -100 <= matrix[i][j] <= 100

按照题意模拟,可以用递归写法

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if(matrix.empty() || matrix[0].empty()) return {};
        vector<int> res;
        int m = matrix.size(), n = matrix[0].size();
        // 确定上下左右四条边的位置
        int up = 0, down = m - 1, left = 0, right = n - 1;
        while (true)
        { 
            for (int i = left; i <= right; i++) res.push_back(matrix[up][i]);
            if (++up > down) break;
            for (int i = up; i <= down; i++) res.push_back(matrix[i][right]);
            if (--right < left) break;
            for (int i = right; i >= left; i--) res.push_back(matrix[down][i]);
            if (--down < up) break;
            for (int i = down; i >= up; i--) res.push_back(matrix[i][left]);
            if (++left > right) break;
        }
        return res;
    }
};

55. 跳跃游戏

难度中等

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标。

示例 1:

输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

示例 2:

输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

提示:

  • 1 <= nums.length <= 3 * 10^4
  • 0 <= nums[i] <= 10^5

尽可能到达最远位置(贪心)。
如果能到达某个位置,那一定能到达它前面的所有位置。

初始化最远位置为 0,然后遍历数组,如果当前位置能到达,并且当前位置+跳数>最远位置,就更新最远位置。最后比较最远位置和数组长度。

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int r=nums[0];
        for(int i=1;i<nums.size();i++)
        {
            if(i>r)
            return false;
            else
            {
                r=max(r,nums[i]+i);
            }
        }
        return true;
    }
};

12.7每日一题

1775. 通过最少操作次数使数组的和相等

难度中等127收藏分享切换为英文接收动态反馈

给你两个长度可能不等的整数数组 nums1nums2 。两个数组中的所有值都在 16 之间(包含 16)。

每次操作中,你可以选择 任意 数组中的任意一个整数,将它变成 16 之间 任意 的值(包含 16)。

请你返回使 nums1 中所有数的和与 nums2 中所有数的和相等的最少操作次数。如果无法使两个数组的和相等,请返回 -1

示例 1:

输入:nums1 = [1,2,3,4,5,6], nums2 = [1,1,2,2,2,2]
输出:3
解释:你可以通过 3 次操作使 nums1 中所有数的和与 nums2 中所有数的和相等。以下数组下标都从 0 开始。
- 将 nums2[0] 变为 6 。 nums1 = [1,2,3,4,5,6], nums2 = [6,1,2,2,2,2] 。
- 将 nums1[5] 变为 1 。 nums1 = [1,2,3,4,5,1], nums2 = [6,1,2,2,2,2] 。
- 将 nums1[2] 变为 2 。 nums1 = [1,2,2,4,5,1], nums2 = [6,1,2,2,2,2] 。

示例 2:

输入:nums1 = [1,1,1,1,1,1,1], nums2 = [6]
输出:-1
解释:没有办法减少 nums1 的和或者增加 nums2 的和使二者相等。

示例 3:

输入:nums1 = [6,6], nums2 = [1]
输出:3
解释:你可以通过 3 次操作使 nums1 中所有数的和与 nums2 中所有数的和相等。以下数组下标都从 0 开始。
- 将 nums1[0] 变为 2 。 nums1 = [2,6], nums2 = [1] 。
- 将 nums1[1] 变为 2 。 nums1 = [2,2], nums2 = [1] 。
- 将 nums2[0] 变为 4 。 nums1 = [2,2], nums2 = [4] 。

提示:

  • 1 <= nums1.length, nums2.length <= 105
  • 1 <= nums1[i], nums2[i] <= 6

这题的贪心挺有意思,后面还可以用哈希优化

首先,根据题意,我们需要计算出数组nums1和nums2之间,最小的操作次数,使得nums1的总和:sum(nums1)与nums2的总和:sum(nums2)两个值相等。那么我们可以根据如下4个步骤来解决这个问题:

  • 步骤1:分别计算sum(nums1)和sum(nums2)的值,确定两个数组加和的差值diff,以及sum(nums1)和sum(nums2)之间的大小关系。
  • 步骤2将总和较小的数组赋值为int[] smaller,将总和较大的数组赋值为int[] bigger。
  • 对于smaller数组中的每个值,我们要执行变大操作,其中:由于最大值是6,所以每个元素s变大的最大跨度是:6 - s;
    对于bigger数组中的每个值,我们要执行变小操作,其中:由于最小值是1,所以每个元素b变大的最大跨度是:b - 1;

贪心

class Solution {
public:
    int minOperations(vector<int>& nums1, vector<int>& nums2) {
        if (nums1.size() > nums2.size() * 6 && nums1.size() * 6 < nums2.size())
            return -1;
        int sum1 = 0, sum2 = 0;;
        for (auto i : nums1)
            sum1 += i;
        for (auto i : nums2)
            sum2 += i;
        vector<int>nums(nums1.size() + nums2.size());
        int x = 0,dif;
        if (sum1 < sum2)
            swap(nums1, nums2), dif = sum2 - sum1;
        else if(sum1==sum2)
        return 0;
        else
            dif = sum1 - sum2;
        for (auto& i : nums1)
            nums[x++] =i-1;
        for (auto& i : nums2)
            nums[x++]=6-i;
        sort(nums.begin(), nums.end());
        for (int i = nums.size() - 1; i >= 0; i--)
        {
            dif -= nums[i];
            if (dif <= 0)
                return nums.size() - i;
        }
        return -1;
    }
};

贪心+哈希

class Solution {
public:
    int minOperations(vector<int>& nums1, vector<int>& nums2) {
        if (nums1.size() > nums2.size() * 6 && nums1.size() * 6 < nums2.size())
            return -1;
        int sum1 = 0, sum2 = 0;;
        for (auto i : nums1)
            sum1 += i;
        for (auto i : nums2)
            sum2 += i;
        int x = 0,dif;
        if (sum1 < sum2)
            swap(nums1, nums2), dif = sum2 - sum1;
        else if(sum1==sum2)
        return 0;
        else
            dif = sum1 - sum2;
            int a[6]={0};
            for (auto i : nums1)
           a[i-1]++;
           for (auto i : nums2)
           a[6-i]++;
           int ans=0;
           for(int i=5;i>0;i--)
           for(int j=0;j<a[i];j++)
           {
           dif-=i;
           ans++;
           if(dif<=0)
           return ans;
           }
        return -1;
    }
};

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

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

相关文章

左(7)--kmp,manacher,morris

前言 仅记录学习笔记&#xff0c;如有错误欢迎指正。 题目&#xff1a; 思路&#xff1a;实现1个函数infect()&#xff0c;把1连接的位置都变为2&#xff0c;此时算一个岛。 如何设计一个并行算法解决这个问题&#xff1f; 在多个cpu中 每次存入分界线的信息&#xff0c;…

拓扑排序与关键路径

一、拓扑排序 1.1 什么是拓扑排序 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序&#xff0c;是将G中所有顶点排成一个线性序列&#xff0c;使得图中任意一对顶点u和v&#xff0c;若边<u,v>∈E(G)&#xff0c;则u在线性序列中出现在v之前。通常&#x…

入驻淘宝成人用品店铺要什么证件?

在淘宝店铺开一家淘宝店铺&#xff0c;必须要有成人用品特种经营许可证&#xff0c;没有申请成人用品特种经营许可证的店铺&#xff0c;在淘宝上是发布不了成人用品类目宝贝的&#xff0c;那么&#xff0c;有的店主就有疑问了&#xff1a;成人用品特种经营许可证要在哪里去申请…

基于Spring Boot+Vue+MySQL的理财平台的设计与实现

目 录 摘 要 I Abstract II 目 录 III 图清单 V 表清单 VII 1 绪论 1 1.1 理财平台的现状与发展 1 1.2吾爱理财平台的研究内容 2 1.3 吾爱理财平台的研究目的和意义 2 1.4 本章小结 3 2 本吾爱理财平台的分析 4 2.1 可行性分析 4 2.2 需求分析 4 2.3 框架介绍 6 2.4 本章小结 …

商用、无版权图片素材网站,赶紧马住。

很多朋友不知道去哪里找图片素材&#xff0c;网上找的质量不高先不说&#xff0c;就怕使用不当造成侵权。今天给大家分享6个可商用&#xff0c;还高质量的图片素材网站。1、菜鸟图库 https://www.sucai999.com/pic.html?vNTYwNDUx菜鸟图库网站素材类型很多&#xff0c;像设计、…

【Python游戏】Python实现一个植物大战僵尸小游戏,非常简单,可以用于做毕业设计哟 | 附源码

前言 halo&#xff0c;包子们下午好 今天给打击整一个植物大战僵尸 无广告版本 哈哈 说实话&#xff0c;现在的小游戏很多都是有广告&#xff0c;多少有点难受 今天给大家直接安排 相关文件 关注小编&#xff0c;私信小编领取哟&#xff01; 当然别忘了一件三连哟~~ 源码点…

一篇博客总结深度学习与反向传播

目录 深度学习的发展过程 深度学习的步骤 定义Neural NetWork 全前向连接 softmax介绍 定义loss函数 定义优化器选择最优参数optimization 反向传播Backpropagation 深度学习介绍 反向传播视频 深度学习的发展过程 perceptron(liner model)感知机——线性模型 perc…

知识图谱-KGE-语义匹配-双线性模型-2018:CP

【paper】 Canonical Tensor Decomposition for Knowledge Base Completion【简介】 这篇是 Facebook 法国巴黎 AI 研究中心发表在 ICML 2018 上的文章&#xff0c;是对传统的张量分解方法 CP&#xff08;Canonical Tensor Decomposition&#xff09;做的分析改进。对传统的几个…

泛微文书定确保电子档案移交接收过程:真实、完整、可用和安全

电子档案的移交接收是电子档案管理流程的重要环节之一。 国家档案局发布的《电子档案移交接收操作规程》中明确了电子档案移交接收的工作流程&#xff0c;规定了电子档案移交接收准备工作和电子档案移交接收操作的要求。 在移交接收过程中&#xff0c;如何快速处理大量的电子…

当软件测试迭代测试时间不够时该如何去做好质量控制呢?

大家好&#xff0c;今天我们一起来聊聊&#xff0c;当我们在工作中尤其是快速迭代版本中测试版本的时间被压缩的很短&#xff0c;甚至不够完成用例执行时怎么去做好质量控制呢&#xff1f; 在我们的日常生活中导致软件测试时间不够的原因有很多&#xff0c;那么在这些不确定的人…

客快物流大数据项目(九十二):ClickHouse的MergeTree系列引擎介绍和MergeTree深入了解

文章目录 ClickHouse的MergeTree系列引擎介绍和MergeTree深入了解 一、MergeTree系列引擎介绍 二、​​​​​​​MergeTree深入了解 1、创建MergeTree表的说明 2、创建MergeTree引擎的表 3、删除MergeTree引擎的表 ClickHouse的MergeTree系列引擎介绍和MergeTree深入了解…

【数据库数据恢复】MySQL数据库误删除未备份的数据恢复案例

MySQL数据库属于关系型数据库。SQL是一种用于操作关系型数据库的结构化语言。关系型数据库就是指在关系模型的基础上建立起来的数据库&#xff0c;是一种借助了集合代数等一些数学方法和数学概念处理数据的数据库。 MySQL数据库具有体积小&#xff0c;速度快&#xff0c;性价比…

【QT开发笔记-基础篇】| 第五章 绘图QPainter | 5.2 界面布局

本节对应的视频讲解&#xff1a;B_站_视_频 https://www.bilibili.com/video/BV1fR4y1k7Kt 上节课&#xff0c;初步展示了本章要实现的效果。本节课开始&#xff0c;就从零新建工程&#xff0c;把效果一一实现 首先先把界面搭建起来&#xff0c;也就是把用到的 Label、ComboB…

R语言实现向量自回归VAR模型

澳大利亚在2008 - 2009年全球金融危机期间发生了这种情况。政府发布了一揽子刺激计划&#xff0c;其中包括2008年12月的现金支付&#xff0c;恰逢圣诞节支出。因此&#xff0c;零售商报告销售强劲&#xff0c;经济受到刺激&#xff0c;收入增加了。 最近我们被客户要求撰写关于…

[附源码]计算机毕业设计JAVA整形美容咨询网站

[附源码]计算机毕业设计JAVA整形美容咨询网站 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybati…

企业为什么要做知识管理?如何进行知识管理?

今天将和大家聊一聊如何通过5大步骤&#xff0c;帮助企业进行知识管理与知识沉淀。 近年来&#xff0c;随着建设的深入&#xff0c;IT不仅成为企业运营的基础&#xff0c;而且在ERP、CRM、OA等信息系统内沉淀的大量知识成为了企业创新的知识源泉&#xff0c;于是知识管理逐渐提…

第十四届蓝桥杯集训——JavaC组第一篇——Eclipse的使用

Eclipse是一个非常经典的开发工具&#xff0c;我们小时候使用的就是这个工具&#xff0c;转眼就这么多年了&#xff0c;依然还在使用&#xff0c;说明这个软件的健壮性还是非常强的。 本博客讲解Eclipse这个IDE的使用&#xff1a; 目录 Eclipse的基础使用 1、常用菜单中英…

C语言有必要学的很深入细致吗?

c语言作为一门高级语言来说&#xff0c;它本身的知识点是很少的&#xff0c;很容易掌握&#xff0c;它没有诸如『类&#xff0c;接口&#xff0c;继承&#xff0c;多态&#xff0c;分派&#xff0c;模板』等等唬人的概念&#xff0c;当然不是说你不能通过c实现这些概念而是这个…

【R语言】计算信息份额模型 - Computes information share component share weights

INTRO 最近又重新开始做一些价格发现相关的研究&#xff0c;目前针对不同市场的同种标的之间价格发现作用的度量&#xff0c;大多采用Hasbrouk&#xff08;1995&#xff09;开发的基于VECM的信息份额模型&#xff0c;通过计算IS指标和CS指标来度量信息份额和价格发现的贡献程度…

【MySQL自学之路】第2天——关系代数计算【理论知识】

目录 前言 基础名词 关系 候选码 关系运算 传统的集合计算&#xff08;二目运算&#xff09; 样例表创建【SQL】 专门的关系运算 后记 销毁已经创建的表 前言 在上一节我们提到了关系型数据库和非关系型数据库之间的关系&#xff0c;我们主要以MySQL关系型数据库为主…