力扣 1775.通过最少操作次数使数的和相等、1014.最佳观光组合、33.搜索旋转排序数组

news2024/11/20 13:18:20

算法总结

最近作者在坚持每日一道中等难度算法题,也是作者考核时经常会碰到的难度,由于经常是到22:30才意识到自己并没有写算法,因此都是打开LeetCode网站随机一题,并未系统性的去学习,这一点值得反思。在做题过程中经常会遇到一些问题,最常见的便是时间复杂度的不理想、符号公式的积累不够深,因此作者把遇到的问题整理出来,从自己的思路,再到题解的思路,以及补充的知识三个方面来分享一些算法题

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

首先先来判断什么样的情况是无法使两数组的和相等,这个时候采取极端方法,当长度较小的数组全为6,而长度较大的全为1,这时候如果都无法长度较小的数组都无法比另外一方大,那就真的没办法了。因此这就是我们的判断条件

        if((nums1.length > nums2.length * 6) || (nums2.length > nums1.length * 6)) {
            return -1;
        }

再之后的思路,因为要操作次数最少,那必然是数组中被操作的那个数弹性很大,也就是和大的数组先调整最大的数,和小的数组先调整最小数。但还是得先判断两个数组的数哪个弹性最大,因此整体思路就是先判断是否能调整,排序,比较弹性,计数并输出结果。
下面给出作者的原始代码:

class Solution {
    public int minOperations(int[] nums1, int[] nums2) {
        if((nums1.length > nums2.length * 6) || (nums2.length > nums1.length * 6)) {
            return -1;
        }
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int distance = sum(nums1) - sum(nums2);
        if(distance == 0) {
            return 0;
        }
        int left = 0;
        int right;

        int count = 0;
        if(distance > 0) {
            right = nums1.length - 1;
            while(distance > 0) {
                if(left >= nums2.length) {
                    distance -= nums1[right] - 1;
                    right--;
                    if(right < 0 && distance > 0) {
                        return -1;
                    }
                    count++;
                    continue;
                }
                if(right < 0) {
                    distance -= 6 - nums2[left];
                    left++;
                    if(left == nums2.length && distance > 0) {
                        return -1;
                    }
                    count++;
                    continue;
                }
                if(6 - nums2[left] > nums1[right] - 1) {
                    distance -= 6 - nums2[left];
                    left++;
                } else {
                    distance -= nums1[right] - 1;
                    right--;
                }
                count++;
            }
        }else {
            right = nums2.length - 1;
            while(distance < 0) {
                if(left >= nums1.length) {
                    distance += nums2[right] - 1;
                    right--;
                    if(right < 0 && distance < 0) {
                        return -1;
                    }
                    count++;
                    continue;
                }
                if(right < 0) {
                    distance += 6 - nums1[left];
                    left++;
                    if(left == nums1.length && distance < 0) {
                        return -1;
                    }
                    count++;
                    continue;
                }
                if(6 - nums1[left] > nums2[right] - 1) {
                    distance += 6 - nums1[left];
                    left++;
                } else {
                    distance += nums2[right] - 1;
                    right--;
                }
                count++;
            }
        }
        return count;
        
        
    }
    int sum(int[] arr) {
        int res = 0;
        for(int i = 0;i < arr.length; i++) {
            res += arr[i];
        }
        return res;
    }
}

但事实证明,作者仍然底蕴不足,此题无论是那种复杂度都惨淡的很

image-20230525195318956

但作者实在脑子不够用了,果断打开题解,一看,不禁感慨,妙!
先贴代码

class Solution {
    public int minOperations(int[] nums1, int[] nums2) {
        int n = nums1.length, m = nums2.length;
        if (6 * n < m || 6 * m < n) {
            return -1;
        }
        int[] cnt1 = new int[7];
        int[] cnt2 = new int[7];
        int diff = 0;
        for (int i : nums1) {
            ++cnt1[i];
            diff += i;
        }
        for (int i : nums2) {
            ++cnt2[i];
            diff -= i;
        }
        if (diff == 0) {
            return 0;
        }
        if (diff > 0) {
            return help(cnt2, cnt1, diff);
        }
        return help(cnt1, cnt2, -diff);
    }

    public int help(int[] h1, int[] h2, int diff) {
        int[] h = new int[7];
        for (int i = 1; i < 7; ++i) {
            h[6 - i] += h1[i];
            h[i - 1] += h2[i];
        }
        int res = 0;
        for (int i = 5; i > 0 && diff > 0; --i) {
            int t = Math.min((diff + i - 1) / i, h[i]);
            res += t;
            diff -= t * i;
        }
        return res;
    }
}

欣赏完之后,来分析,首先第一步,作者很荣幸的跟题解想到了一样的判断条件,想法在前面已经阐述过了,便不多言了
接着来看第二步,官方给了一个类似于计数器的做法,Java中 new出来的数组默认值都是0或者null,一边计数一边算差距,之后对差距进行判断,用自定义函数的返回值作为返回值,这相信大家都能懂。

        int[] cnt1 = new int[7];
        int[] cnt2 = new int[7];
        int diff = 0;
        for (int i : nums1) {
            ++cnt1[i];
            diff += i;
        }
        for (int i : nums2) {
            ++cnt2[i];
            diff -= i;
        }
        if (diff == 0) {
            return 0;
        }
        if (diff > 0) {
            return help(cnt2, cnt1, diff);
        }
        return help(cnt1, cnt2, -diff);

那么重点就是这个help函数是如何help时间复杂度的降低的,来细看

    public int help(int[] h1, int[] h2, int diff) {
        int[] h = new int[7];
        for (int i = 1; i < 7; ++i) {
            h[6 - i] += h1[i];
            h[i - 1] += h2[i];
        }
        int res = 0;
        for (int i = 5; i > 0 && diff > 0; --i) {
            int t = Math.min((diff + i - 1) / i, h[i]);
            res += t;
            diff -= t * i;
        }
        return res;
    }

作者当时看到代码就觉得,这代码和作者写的有点相似,只能说,同跨过一条槛,有人风风光光,有人狼狈不堪。回到正题,该函数的计数器,记录的是弹性值,因为h1[i]中的i代表的是数组里的数值,所以记录他最多能增加/减少多少,之后的循环就从最大弹性值开始一步步减,最后得出结果
总结:作者感觉题解对比作者的代码,最大的亮点就是采用计数,这样就少了很多弯弯绕绕的if语句

1014.最佳观光组合

作者看到这道题便想到了盛最多水的容器,于是打算依样画葫芦,但最后也就是画虎类犬罢了,后来作者想起了动态规划的定义,发现这确实有点像,苦思冥想,在看到题目中的一行话时幡然醒悟

value[i] + value[j] + i - j

这句话看似普普通通,但当我们调换顺序时,便能发现其中奥秘

value[i] + i + value[j] - j

把它当作两个变量来看,我们就可以想到一次遍历,不停判断max值即可,贴出代码

class Solution {
    public int maxScoreSightseeingPair(int[] values) {
        int max = 0;
        int ax = values[0] + 0;
        for(int i = 1; i < values.length; i++) {
            max = Math.max(max, ax + values[i] - i);
            ax = Math.max(ax, values[i] + i);
        }
        return max;
    }
}

总结:一定要抓住内在的真正变量,抓住规律

接下来再来一道拆开来看的题目,这道题作者很幸运的做的较为出彩

33.搜索旋转排序数组

首先还是先来判断什么情况是必然找不到的,因为他是旋转过的,所以在(nums[nums.length - 1] , nums[0])是肯定找不到的,其他的之后再说,因此给出第一个判断条件

if(target < nums[0] && target > nums[nums.length - 1]) {
            return -1;
}

之后,当我们分开看,其实这个数组可以看成是两个不会有重复且递增的数组拼接在了一起,所以判断target 可能在哪段数组,在for循环寻找,即可

class Solution {
    public int search(int[] nums, int target) {
        if(target < nums[0] && target > nums[nums.length - 1]) {
            return -1;
        }
        if(target >= nums[0]) {
            for(int i = 0; i < nums.length; i++) {
                if(target == nums[i]) {
                    return i;
                }
            }
        }else {
            for(int i = nums.length-1; i >= 0; i--) {
                if(target == nums[i]) {
                    return i;
                }
            }
        }
        return -1;
    }
}

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

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

相关文章

航天科技AIRIOT物联会【智慧物联主题沙龙】在沈阳举办

2023年5月24日&#xff0c;由航天科技控股集团股份有限公司&#xff08;简称“航天科技”&#xff09;智慧物联事业部主办的《AIRIOT物联会-智慧物联主题分享沙龙》在沈阳举办&#xff0c;此次会议邀请到来自光伏、燃气、能源、水务、园区、工厂等行业的众多企业代表参加&#…

0起步用GPT+知乎赚了点小钱,人人可复制

大家好&#xff0c;我是五竹。 前段时间分享了一篇关于用ChatGPT赚点小钱的实战&#xff1a;TMD&#xff0c;被人偷窥了一个月&#xff01;结果上周末的时候在知乎追了一个关于Claude的热点&#xff0c;发布了一篇注册Claude的文章&#xff0c;结果小小的“爆了”一下&#xf…

Qt文件系统源码分析—第五篇QTemporaryFile

深度 本文主要分析Windows平台&#xff0c;Mac、Linux暂不涉及 本文只分析到Win32 API/Windows Com组件/STL库函数层次&#xff0c;再下层代码不做探究 本文QT版本5.15.2 类关系图 QTemporaryFile继承QFile QFile、QSaveFile继承QFileDevice QFileDevice继承QIODevice Q…

如何查看一个 docker 镜像有哪些版本

如何查看一个 docker 镜像有哪些版本 因为通过 docker search 并不能查看某个镜像的版本信息&#xff0c;如我需要特定版本的 redis 那怎么办呢~ 本文提供了如下几种方式&#xff0c;大家可以分别逐个尝试下~ 为什么有几种方式呢&#xff0c;因为官方的查找镜像网址 Docker H…

使用audition测试USBaudio数据回传延时

一&#xff0c;简介 本文主要介绍如何使用Audition软件来测试STM32 USB audio上行音频数据的延时。 二&#xff0c;准备工作 Audition&#xff0c;ASIO驱动&#xff0c;STM32枚举的USB Audio高速声卡测试板。 二&#xff0c;硬件连接 将STM32的IIS的data in和data out使用…

四款AI视频翻译产品横评

本文内容节选自 Paxi.ai 的文章分享&#xff0c;从其中摘录了我觉得有意思的一部分。Paxi.ai 是一个基于 GPT-4 打造的帮用户快速使用AI的AI工具&#xff0c;通过与它的小助手对话可以了解各种AI的产品功能和使用方式。对本文内容感兴趣的朋友可以上他们官网查看。 有没有想过把…

go embed 实现gin + vue静态资源嵌入

前言 golang1.16出来以后&#xff0c;早就有打算把ckman项目的前端代码打包更换成embed。在此之前&#xff0c;使用的是pkger进行的打包。 但是今天打包时却报了个错&#xff1a; 而且通过各种手段尝试均无果之后&#xff0c;果断把决定立即将其更换为embed进行资源嵌入管理。…

华为OD机试真题 Java 实现【寻找符合要求的最长子串】【2023Q1 200分】

一、题目描述 给定一个字符串 s &#xff0c;找出这样一个子串&#xff1a; 该子串中的任意一个字符最多出现2次&#xff1b;该子串不包含指定某个字符&#xff1b; 请你找出满足该条件的最长子串的长度。 二、输入描述 第一行为要求不包含的指定字符&#xff0c;为单个字…

一个神奇的工具,让URL地址都变成了“ooooooooo“

一个神奇的工具&#xff0c;让URL地址都变成了"ooooooooo" 一、核心代码二、URL编码/解码 最近发现一个有意思工具&#xff0c;就是将一个URL地址转换为都是 ooooooooo 的样子&#xff0c;通过转换后的地址访问可以转换回到原始地址&#xff0c;转换的逻辑有点像短链…

mysql8绿色版安装教程

最近在安装mysql8绿色版&#xff0c;以下是安装过程中的一些步骤&#xff1a; 1&#xff1a;解压zip压缩包至想要安装的目录&#xff0c;比如解压到D:\mysql\mysql-8.0.29-winx64 2&#xff1a;在解压目录D:\mysql-8.0.29-winx64中创建MySQL配置文件my.ini 配置文件my.ini内容…

Unity3D安装:离线安装 Unity

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 3D工具集&#xff1a; NSDT简石数字孪生 在没有 Hub 的情况下离线安装 Unity Unity 下载助手 (Download Assistant) 支持离线部署。在这种部署方式中&#xff0c;可下载用于安装 Unity 的所有文件&#xff0c;然后生成脚本…

【日常】如何增加粉丝的粘性?

【日常】如何增加粉丝的粘性&#xff1f; 1、前言2、官方活动3、作品质量4、打造自己的社区 1、前言 不知不觉间&#xff0c;铁粉已经过千了&#xff0c;粉丝数也即将两万&#xff0c;总而言之&#xff0c;越努力&#xff0c;越幸运&#xff0c;付出就有回报&#xff08;当然在…

面了个阿里拿36K出来的,真是砂纸擦屁股,给我漏了一手

今年的春招已经结束&#xff0c;很多小伙伴收获不错&#xff0c;拿到了心仪的 offer。 各大论坛和社区里也看见不少小伙伴慷慨地分享了常见的面试题和八股文&#xff0c;为此咱这里也统一做一次大整理和大归类&#xff0c;这也算是划重点了。 俗话说得好&#xff0c;他山之石…

减肥瘦身自律APP软件开发功能有哪些?

减肥瘦身是很多女人一生都在奋斗的目标&#xff0c;如果找不对方法&#xff0c;减肥效果事倍功半还可能会反弹&#xff0c;所以越来越多的人推崇健康科学的减肥理念&#xff0c;把瘦身的重心转移到饮食和运动管理上&#xff0c;于是市场上出现了减肥瘦身自律类的APP软件&#x…

一位27岁软件测试员,测试在职近5年,月薪还不到2W,担心被应届生抢走饭碗

工作了近5年&#xff0c;一个月工资不到20K&#xff0c;担心被应届毕业生取代&#xff01;互联网的快速发展伴随着员工适者生存的加速&#xff0c;测试员的薪资也在不断增长&#xff0c;以3年、5年、8年为一条分水岭。如果人们的能力和体力不够&#xff0c;他们就会被淘汰。看起…

leetcode 146.LRU 缓存

题目链接&#xff1a;leetcode 146 1.题目 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中&#xff0…

第四届全国人工智能大赛答疑分享会等你围观

为了帮助参赛团队更精准地理解赛题、更合理地运用AI相关技术&#xff0c;第四届全国人工智能大赛组委会诚邀鹏城实验室副研究员杨文瀚老师为大家进行AI视觉特征编码赛题解析与答疑&#xff0c;并分享《交通场景下的高效紧致特征表达》。 此次答疑分享会将于5月26日&#xff08…

供应商管理软件如何帮助企业提高盈利能力?

为了在当今快节奏的商业环境中保持竞争力和刺激增长&#xff0c;供应商管理技术正变得至关重要。供应商管理是任何公司最关键的因素之一&#xff0c;其中包括考核供应商、采购及招投标管理、协同管理等多项任务。 随着成熟的供应商管理软件的出现&#xff0c;企业主现在可以优…

三大特性之多态

文章目录 静态的多态动态的多态虚函数虚函数的重写&#xff08;覆盖&#xff09;利用虚函数重写实现多态重写的两个例外1.协变2.析构函数的函数名不同 C11的override和final 重载&#xff0c;重写&#xff08;覆盖&#xff09;&#xff0c;重定义&#xff08;隐藏&#xff09;抽…

什么是客户旅程,为什么它很重要?

多年来&#xff0c;企业专注于客户接触点来衡量客户满意度。近年来&#xff0c;企业已经看到接触点并不能捕捉到全貌。客户接触点只能在一个时间点衡量满意度。他们不一定保证客户对他们的整个旅程感到满意。但什么是客户接触点&#xff1f;是客户与企业互动的特定时刻&#xf…