day59-day60【代码随想录】二刷数组

news2024/11/16 7:47:04

文章目录

  • 前言
  • 一、移动零(力扣283)【双指针】
  • 二、轮转数组(力扣189)
  • 三、寻找数组的中心下标(力扣728)
  • 四、和为 K 的子数组(力扣560)
  • 五、按奇偶排序数组 II(力扣922)【双指针】
  • 六、爱吃香蕉的珂珂(力扣875)【二分法】
  • 每日一题:按位与为零的三元组(力扣982)
  • 每日一题:经营摩天轮的最大利润(力扣1599)


前言

1、移动零
2、轮转数组
3、寻找数组的中心下标
4、和为 K 的子数组
5、按奇偶排序数组||
6、爱吃香蕉的珂珂


一、移动零(力扣283)【双指针】

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。
在这里插入图片描述

class Solution {
    public void moveZeroes(int[] nums) {
        int slowIndex =0;
        int fastIndex = 0;
        for(;fastIndex<nums.length;fastIndex++){
            if(nums[fastIndex]!=0){
                nums[slowIndex++]=nums[fastIndex];
            }
        }
        //剩下的补零
        for(int i=slowIndex;i<nums.length;i++){
            nums[i] = 0;
        }
    }
}

二、轮转数组(力扣189)

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

最简单的想法 开辟一个新的数组暂时存放元素 空间复杂度为O(n)
还要注意一点:本题还有一个小陷阱,题目输入中,如果k大于nums.length了应该怎么办? ------>取模运算

class Solution {
    public void rotate(int[] nums, int k) {
        int Index =0;
        int length = nums.length;
        int moveTme = k%length;
        int[] temp = new int[moveTme];

        if(nums.length==1) return ;
        for(int i=length-moveTme;i<length;i++){
            temp[Index++] = nums[i];
        }

        int fastIndex = length-1;
        for(int i=length-moveTme-1;i>=0;i--){
            nums[fastIndex--] = nums[i];
        }
        int slowIndex = 0;

        for(int i=0;i<=fastIndex;i++){
            nums[slowIndex++] = temp[i];
        }
    }
}

方法二:翻转数组
第一步:把整个数组进行翻转
第二步:分为两部分:【0:k-1】 【k:nums.length-1】分别一次翻转即可

class Solution {
    public void rotate(int[] nums, int k) {
        //翻转数组
        int moveTime = k%nums.length;
        reverse(nums,0,nums.length-1);
        reverse(nums,0,moveTime-1);
        reverse(nums,moveTime,nums.length-1);
    }
    public void reverse(int[] nums,int start,int end){
        while(start<end){
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start+=1;
            end-=1;
        }
    }
}

三、寻找数组的中心下标(力扣728)

给你一个整数数组 nums ,请计算数组的 中心下标 。

数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。

如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。

如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。
在这里插入图片描述
一开始会想到双指针,但是需要修补很多边边角角,较为繁琐

左求和*2+中心索引值 = 总和

class Solution {
    public int pivotIndex(int[] nums) {
        int sum =0;
        for(int i=0;i<nums.length;i++){
            sum+=nums[i];
        }
        int left =0;
        int right=0;
        for(int i=0;i<nums.length;i++){
            sum -=nums[i];
            if(sum==left) return i;
            left += nums[i];
        }
        return -1;
    }
}

四、和为 K 的子数组(力扣560)

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数 。
在这里插入图片描述

分析:
第一感觉是滑动窗口,但是在试了很久之后发现并不可行。
为什么这题不可以用双指针/滑动窗口:因为nums[i]可以小于0,也就是说右指针i向后移1位不能保证区间会增大,左指针j向后移1位也不能保证区间和会减小。给定j,i的位置没有二段性,vice versa(反之亦然)。

暴力求解:

public class Solution {
    public int subarraySum(int[] nums, int k) {
        int count = 0;
        for (int start = 0; start < nums.length; ++start) {
            int sum = 0;
            for (int end = start; end >= 0; --end) {
                sum += nums[end];
                if (sum == k) {
                    count++;
                }
            }
        }
        return count;
    }
}

前缀和+哈希表
基于方法一利用数据结构进行进一步的优化
在这里插入图片描述

五、按奇偶排序数组 II(力扣922)【双指针】

给定一个非负整数数组 nums, nums 中一半整数是 奇数 ,一半整数是 偶数 。

对数组进行排序,以便当 nums[i] 为奇数时,i 也是 奇数 ;当 nums[i] 为偶数时, i 也是 偶数 。

你可以返回 任何满足上述条件的数组作为答案 。
在这里插入图片描述

class Solution {
    public int[] sortArrayByParityII(int[] nums) {
        int jishuIndex = nums.length-1;
        int oushuIndex = 0;

        while(jishuIndex>0 && oushuIndex<nums.length-1){
            while(jishuIndex>0 && nums[jishuIndex]%2==1){
                jishuIndex-=2;
            }
            while(oushuIndex<nums.length-1 && nums[oushuIndex]%2==0){
                oushuIndex+=2;
            }
            //交换元素:
            if(jishuIndex>0 && oushuIndex<nums.length-1){
                int temp = nums[oushuIndex];
                nums[oushuIndex] = nums[jishuIndex];
                nums[jishuIndex] = temp;
                oushuIndex+=2;
                jishuIndex-=2;
            }
        }
        return nums;
    }
}

六、爱吃香蕉的珂珂(力扣875)【二分法】

珂珂喜欢吃香蕉。这里有 n 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警卫已经离开了,将在 h 小时后回来。

珂珂可以决定她吃香蕉的速度 k (单位:根/小时)。每个小时,她将会选择一堆香蕉,从中吃掉 k 根。如果这堆香蕉少于 k 根,她将吃掉这堆的所有香蕉,然后这一小时内不会再吃更多的香蕉。

珂珂喜欢慢慢吃,但仍然想在警卫回来前吃掉所有的香蕉。

返回她可以在 h 小时内吃掉所有香蕉的最小速度 k(k 为整数)。
在这里插入图片描述
分析:
珂珂可以一小时吃一根香蕉 也可以一小时吃两根香蕉,最多一小时可以吃香蕉堆的最大值,速度可以一直增加,增加速度太慢,所以使用二分法增加

class Solution {
    public int minEatingSpeed(int[] piles, int h) {
        int maxBanana = 0;
        //先找到二分查找的边界值
        for(int i=0;i<piles.length;i++){
            if(piles[i]>maxBanana){
                maxBanana = piles[i];
            }
        }
        int left = 1;
        int mid = 0;
        int k = maxBanana;
        while(left<maxBanana){
            mid = (left+maxBanana)/2;
            //二分法 把此时的速度传进去,看看需要多长时间 比h大还是小
            long res = checkEat(mid,piles);
            if(res>h){
                //k应该增加;
                left=mid+1;
            }else{
                maxBanana = mid;
                k=mid;
            }
        }
        return k;
    }


    public long checkEat(int speed,int[] piles){
        long time = 0;
        for(int i=0;i<piles.length;i++){
            if(piles[i]<speed){
                time++;
            }else{
                int h = piles[i]/speed;
                if(piles[i]%speed==0){
                    time+=h;
                }else time+=(h+1);
            }
        }
        return time;
    }
}

每日一题:按位与为零的三元组(力扣982)

给你一个整数数组 nums ,返回其中 按位与三元组 的数目。

按位与三元组 是由下标 (i, j, k) 组成的三元组,并满足下述全部条件:

0 <= i < nums.length
0 <= j < nums.length
0 <= k < nums.length
在这里插入图片描述

class Solution {
    public int countTriplets(int[] nums) {
        int[] map = new int[1<<16];

        int count = 0;
        //nums[i] 和 nums[j]的结果

        for(int x:nums){
            for(int y:nums){
                ++map[x & y];
            }
        }
        for(int x:nums){
            for(int y=0;y<1<<16;y++){
                if((x&y)==0){
                    count += map[y];
                }
            }
        }
        return count;
    }
}

每日一题:经营摩天轮的最大利润(力扣1599)

正在经营一座摩天轮,该摩天轮共有 4 个座舱 ,每个座舱 最多可以容纳 4 位游客 。你可以 逆时针 轮转座舱,但每次轮转都需要支付一定的运行成本 runningCost 。摩天轮每次轮转都恰好转动 1 / 4 周。

给你一个长度为 n 的数组 customers , customers[i] 是在第 i 次轮转(下标从 0 开始)之前到达的新游客的数量。这也意味着你必须在新游客到来前轮转 i 次。每位游客在登上离地面最近的座舱前都会支付登舱成本 boardingCost ,一旦该座舱再次抵达地面,他们就会离开座舱结束游玩。

你可以随时停下摩天轮,即便是 在服务所有游客之前 。如果你决定停止运营摩天轮,为了保证所有游客安全着陆,将免费进行所有后续轮转 。注意,如果有超过 4 位游客在等摩天轮,那么只有 4 位游客可以登上摩天轮,其余的需要等待 下一次轮转 。

返回最大化利润所需执行的 最小轮转次数 。 如果不存在利润为正的方案,则返回 -1 。

在这里插入图片描述

题目太费解。重新描述一下,为"最佳跑路时机"。 迪士尼把它的摩天轮游乐场卖给你了,约好明天付款,今天你先试运行一下。但你其实没有那么多钱,今天必须跑路。 摩天轮不能停,从早上开门就必须一直按固定的速率旋转。 电力公司不信任你,每旋转一格,电力公司就实时从你的账中划走一笔电费runningCost。 你有未卜先知的能力,知道每个时刻,达到的顾客数目有多少。而且这些顾客都是死忠,坐不上摩天轮就不走。 每个顾客在坐上去的同时,扫码转账给你boardingCost。 问:你什么时候拉闸跑路,钱最多?天上的顾客等救援机构来了再说。。。

class Solution {
    public int minOperationsMaxProfit(int[] customers, int boardingCost, int runningCost) {
        int wait =0;
        int person=0;
        int maxProfit = 0;
        int res = -1;
        int profit =0;
        //首先肯定需要遍历顾客数量
        for(int i=0;i<customers.length || person>0;i++){
            if(i<customers.length){
                person += customers[i];
            }
            profit += Math.min(person,4)* boardingCost-runningCost;
            person-=Math.min(person,4);
            if(profit>maxProfit){
                maxProfit = profit;
                res = i+1;
            }
        }
        return res;
    }
}

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

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

相关文章

【SPSS】多因素方差分析详细操作教程(附案例实战)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

【微信小程序-原生开发】实用教程14 - 列表的分页加载,触底加载更多(含无更多数据的提醒和显示,自定义组件)

此页可在动态列表的基础上完善&#xff0c;也可以单独学习 【微信小程序-原生开发】实用教程10 - 动态列表的新增、修改、删除 https://blog.csdn.net/weixin_41192489/article/details/128835069 效果预览 核心技术 列表的分页加载 skip 跳跃到指定下标开始查询limit 限制返…

Vulnhub系列:SickOS1.1

靶机地址&#xff1a;SickOS1.1渗透思路&#xff1a;信息收集对于目标靶机进行扫描&#xff0c;可以利用nmap或arp-scan -l进行查询&#xff0c;查询到靶机后&#xff0c;探测其开放的端口&#xff0c;常见的端口21、22、80、3306、445等等&#xff0c;对于不同的端口进行不同的…

博途PLC开放式以太网通信之TRCV_C指令编程应用

博途PLC开放式以太网通信TSENG_C指令应用,请参看下面的文章链接: 博途PLC 1200/1500PLC开放式以太网通信TSEND_C通信(UDP)_plc的udp通信_RXXW_Dor的博客-CSDN博客开放式TSEND_C通信支持TCP 、UDP等,关于TSEND_C的TCP通信可以参看下面这篇文章:博途PLC 1200/1500PLC开放式…

存储器分类

存储器(Memory)包括&#xff1a; RAM(Random Access Memory)&#xff08;计算机运行内存、CPU的L1/L2 Cache等&#xff09;、 ROM(Read Only Memory)&#xff08;用于BIOS等固化程序/数据的存储&#xff09;和 Flash&#xff08;可用于机械硬盘等&#xff09;。 存储器&#x…

现代神经网络(VGG),并用VGG16进行实战CIFAR10分类

专栏&#xff1a;神经网络复现目录 本章介绍的是现代神经网络的结构和复现&#xff0c;包括深度卷积神经网络&#xff08;AlexNet&#xff09;&#xff0c;VGG&#xff0c;NiN&#xff0c;GoogleNet&#xff0c;残差网络&#xff08;ResNet&#xff09;&#xff0c;稠密连接网络…

Blender Python材质处理入门

本文介绍在 Blender 中如何使用 Python API 获取材质及其属性。 推荐&#xff1a;用 NSDT场景设计器 快速搭建3D场景。 1、如何获取材质 方法1、 获取当前激活的材质 激活材质是当前在材质槽中选择的材料。 如果你选择一个面&#xff0c;则活动材料将更改为分配给选定面的材质…

ceph-ansible部署Ceph Pacific版本集群

文章目录环境规划节点初始化设置ssh免密主机名解析时间同步关闭防火墙部署ceph下载ceph-ansible修改配置文件执行部署验证集群状态扩容mon节点扩容osd节点环境规划 总共9个节点&#xff0c;3个mon节点&#xff0c;6个osd节点&#xff0c;每个osd节点3块50G的osd磁盘 主机名os…

Linux命令系统总结

Linux Linux常用操作_linux基本操作_槑の少年的博客-CSDN博客 help help 命令 &#xff1a;获得 shell 内置命令的帮助信息&#xff0c;常用形式 help cd ls --help 文件夹级 常用参数&#xff1a; cd 绝对路径 &#xff1a;切换路径 cd 相对路径 &#xff1a;切换路径 …

移动web(三)

her~~llo&#xff0c;我是你们的好朋友Lyle&#xff0c;是名梦想成为计算机大佬的男人&#xff01; 博客是为了记录自我的学习历程&#xff0c;加强记忆方便复习&#xff0c;如有不足之处还望多多包涵&#xff01;非常欢迎大家的批评指正。 媒体查询 目标&#xff1a;能够根据…

凌恩生物资讯

凌恩生物转录组项目包含范围广&#xff0c;项目经验丰富&#xff0c;人均10年以上项目经验&#xff0c;其中全长转录组测序研究基因结构已经成为发文章的趋势&#xff0c;研究物种包括高粱、玉米、拟南芥、鸡、人和小鼠、毛竹、棉花等。凌恩生物提供专业的全长转录组测序及分析…

【微信小程序】-- 页面导航 -- 编程式导航(二十三)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &…

面向对象的使用

目录1. 类和对象的概念类对象类和对象的关系2. 定义简单的类(只包含方法&#xff09;3. 创建对象4. self参数5. 类的初始化方法在初始化方法内部定义属性在初始化方法内部接收参数定义属性6. 类的内置方法使用__del__ 方法__str__ 方法7. 身份运算符is 与 区别&#xff1a;8. …

【Copula】考虑风光联合出力和相关性的Copula场景生成(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

文献资源最多的文献下载神器,99.99%的文献都可下载

用对工具事半功倍&#xff0c;查找下载文献用对工具能节约大量的时间和精力去做更多的事情。 文献党下载器&#xff08;wxdown.org&#xff09;&#xff0c;几乎整合了所有文献数据库资源&#xff0c;涵盖各种文献类型&#xff0c;包含全部学科。文献党下载器整合的资源如&…

Spring-Cloud-Gateway的过滤器的执行顺序问题

过滤器的种类 Spring-Cloud-Gateway中提供了3种类型的过滤器&#xff0c;分别是&#xff1a;路由过滤器、Default过滤器和Global过滤器。 路由过滤器和Default过滤器 路由过滤器和Default过滤器本质上是同一种过滤器&#xff0c;只不过作用范围不一样&#xff0c;路由过滤器…

【水下图像增强】Enhancing Underwater Imagery using Generative Adversarial Networks

原始题目Enhancing Underwater Imagery using Generative Adversarial Networks中文名称使用 GAN 增强水下图像发表时间2018年1月11日平台ICRA 2018来源University of Minnesota, Minneapolis MN文章链接https://arxiv.org/abs/1801.04011开源代码官方&#xff1a;https://gith…

Linux 进程:exec函数簇

目录&#xff08;1&#xff09;execl&#xff08;2&#xff09;execlp&#xff08;3&#xff09;execle&#xff08;4&#xff09;execv&#xff08;5&#xff09;execvp&#xff08;6&#xff09;execve在进程控制中提到&#xff0c;子进程的最大价值在于程序替换&#xff0c;…

Android动态权限获取官方实现之easypermission

Android动态权限获取官方实现之easypermission Android 6.0之后&#xff0c;基于用户隐私和安全考虑&#xff0c;敏感权限都开始采用动态运行时机制获取&#xff0c;于是就出现如果你不向用户申请权限&#xff08;弹窗&#xff0c;用户选择&#xff09;&#xff0c;有些功能就…

Flutter Android 打包保姆式全流程 2023 版

大家好&#xff0c;我是 17。 为什么要写这篇文章呢&#xff1f;对于一没有 android 开发经验&#xff0c;从未有过打包经历的新人来说&#xff0c;要想成功打包&#xff0c;是很困难的。因为受到的阻碍太多&#xff0c;是完全陌生的领域&#xff0c;几乎是寸步难行。如果有老…