Java双指针专题——1.移动0 2.复写0 3.快乐数4.盛最多水的容器5.有效三角形的个数 6.和为s的两个数字7.三数之和8.四数之和

news2024/11/11 5:07:10

目录

1.移动0

2.复写0

3.快乐数

4.盛最多水的容器

5.有效三角形的个数 

6.和为s的两个数字

7.三数之和

8.四数之和


 

1.移动0

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

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

 

示例 1:

输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:

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

fa53648477594d3bbfa0212ca2449ba5.png

d2ca1c23b180437eaa51592d75578a64.jpg

 

class Solution {
    public void moveZeroes(int[] array) {
         int index0=-1;
        for (int i = 0; i < array.length; i++) {
            if(array[i]!=0){
                if(index0!=-1){//(还没初始化)如果第一个0还没出现,那就不管现在出现的非0的数字
                //如果出现了那就交换这个数字和第一个出现0的位置                                             
                    int temp=array[i];
                    array[i]=array[index0];
                    array[index0]=temp;
                    index0++;
                }
            }
            else{//遍历到0,初始化第一个0出现的下标
                if(index0==-1){
                    index0=i;
                }
            }
        }
    }
}
//目标就是让0全部放在末尾

2.复写0

给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。

注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。

 

示例 1:

输入:arr = [1,0,2,3,0,4,5,0]
输出:[1,0,0,2,3,0,0,4]
解释:调用函数后,输入的数组将被修改为:[1,0,0,2,3,0,0,4]
示例 2:

输入:arr = [1,2,3]
输出:[1,2,3]
解释:调用函数后,输入的数组将被修改为:[1,2,3]

根据双指针的异地操作将他优化成原地操作。

变成原地的过程会发现,覆盖问题,根据“删除数组中值为val的元素”。 

f4181d15e4a444f0bbe17084148a0904.png

class Solution {
    public void duplicateZeros(int[] arr) {
        int cur=0,dest=-1,n=arr.length;
        //1.找到最后一个需要腹泻的数字
        while(cur<n){
            if(arr[cur]==0) dest+=2;
            else dest+=1;
            if(dest>=n-1)  break;
            cur++;

        }
        //2.处理边界情况
        if(dest==n){
            arr[n-1]=0;
            cur--;
            dest-=2;
        }
        //3.从后向前完成复写
        while(cur>=0){
            if(arr[cur]!=0) {
                arr[dest--]=arr[cur--];
            }else{
                arr[dest--]=0;
                arr[dest--]=0;
                cur--;
            }
        }

    }
}

3.快乐数

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

 

示例 1:

输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

  d0982f3fcc174fd68dd7b3b89fda25fd.png

451633cacf1d425fb9888455b7289794.png

class Solution {
    public int bitSum(int n){
        int sum=0;
        while(n!=0){
            int t=n%10;
            sum+=t*t;
            n/=10;
        }
        return sum;
    }
    public boolean isHappy(int n) {
        int slow=n,fast=bitSum(n);
        while(slow!=fast){
            slow=bitSum(slow);
            fast=bitSum(bitSum(fast));
        }
        return slow==1;
    }
}

4.盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

 

示例 1:d66b1935e9c94d7ea124939d8b9c6f39.png

 

输入:[1,8,6,2,5,4,8,3,7]
输出:49 
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

e83269a600e847ec9cff27ccf7982054.png

class Solution {
    public int maxArea(int[] height) {
        int left=0,right=height.length-1,ret=0;
        while(left<right){
            int v=Math.min(height[left],height[right])*(right-left);
            ret=Math.max(ret,v);
            //左右两个值中相对小的移动;
            if(height[left]<height[right]) left++;
            else right--;
        }
        return ret;
    }
}

 

5.有效三角形的个数 

给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。

 

示例 1:

输入: nums = [2,2,3,4]
输出: 3
解释:有效的组合是: 
2,3,4 (使用第一个 2)
2,3,4 (使用第二个 2)
2,2,3

e71f0c6b38d54484af143fbc94964467.png

暴力解

class Solution {
    public int triangleNumber(int[] nums) {
        Arrays.sort(nums);
        if(nums.length<3){
            return 0;
        }
        int count=0;
        for(int i=0;i<nums.length;i++){
            for(int j=i+1;j<nums.length;j++){
                for(int k=j+1;k<nums.length;k++){
                    if(nums[j]+nums[i]>nums[k]){
                         count++;
                    }
                            
                 }
                
            }
        }
        return count;
    }
}

 9dd8e2a2119543589f85f37998f7f509.png

class Solution {
    public int triangleNumber(int[] nums) {
        //利用单调性的双指针
        //1.排序
        Arrays.sort(nums);
        //2.利用双指针;
        int ret=0,n=nums.length;
        for(int i=n-1;i>=2;i--){//固定最大的数
        //利用left,right指针统计符合要求的三元组的个数
             int left=0,right=i-1;
            while(left<right){
                if(nums[left]+nums[right]>nums[i]){
                    ret+=right-left;
                    right--;
                }else{
                    left++;
                }
            }

        }
        return ret;
    }
}

 

6.和为s的两个数字

d79e8b594cfc463798a8c14777db26ef.png

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int i = 0, j = nums.length - 1;
        while(i < j) {
            int s = nums[i] + nums[j];
            if(s < target) i++;
            else if(s > target) j--;
            else return new int[] { nums[i], nums[j] };
        }
        return new int[0];
    }
}

7.三数之和

d9b6801d940d4c3d9abd7d67aeac6b41.png

 17dbba3622f44ce3a6b6f81d441ed8e4.png

63d0637be41d40aeb9b63f55f3d7c866.png

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {

        List<List<Integer>> ret=new ArrayList<>();
        Arrays.sort(nums);
        int n=nums.length;
        for(int i=0;i<n;){
            if(nums[i]>0) break;//小优化
            int left=i+1,right=n-1,target=-nums[i];
            while(left<right){
                int sum=nums[left]+nums[right];
                if(sum>target) right--;
                else if(sum<target) left++;
                else{
                    ret.add(new ArrayList<Integer>(Arrays.asList(nums[i],nums[left],nums[right])));
                    left++;
                    right--;
                    //去重
                    while(left<right&&nums[left]==nums[left-1]) left++;
                    while(left<right&&nums[right]==nums[right+1]) right--;
                }
            }
            i++;
            while(i<n&&nums[i]==nums[i-1]) i++;
        }
        return ret;
    }
}

8.四数之和

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案 。

 

示例 1:

输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]

 

排序+双指针 

5550b6e489324bfc85abad38f35fc855.png 

 

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> ret=new ArrayList<>();
        Arrays.sort(nums);
        int n=nums.length;
        for(int i=0;i<nums.length;){
            for(int j=i+1;j<nums.length;){
               int left=j+1,right=n-1;
               long aim=(long)target-nums[i]-nums[j];//最后看测试用例·然后改这里;
                while(left<right){
                    int sum=nums[left]+nums[right];
                    if(sum>aim) right--;
                    else if(sum<aim) left++;
                    else{
                       // ret.add(new ArrayList<Integer>(Arrays.asList(nums[i],nums[j],nums[left++],nums[right--])));
                        ret.add(Arrays.asList(nums[i],nums[j],nums[left++],nums[right--]));
                        //这两种我看都是可以的
                        //去重1
                        while(left<right&&nums[left]==nums[left-1]) left++;
                        while(left<right&&nums[right]==nums[right+1]) right--;

                    }

                }//去重2
                j++;
                while(j<n&&nums[j]==nums[j-1]) j++;
            }
            //去重3
            i++;
            while(i<n&&nums[i]==nums[i-1]) i++;
        }
        return ret;
    }
}

 

 

 

 

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

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

相关文章

实施预测性维护的策略和实践探讨

随着工业设备复杂性和关键性的增加&#xff0c;传统的计划性维护方法已经无法满足现代工业的需求。预测性维护作为一种基于设备状态和数据分析的维护策略&#xff0c;能够准确预测设备故障&#xff0c;降低停机时间&#xff0c;提高生产效率和设备可靠性。在实施预测性维护之前…

初出茅庐的小李博客之RTC时间设置

串口上位机设置RTC时间进行校准 方式1&#xff1a;发送固定格式时间解析 代码&#xff1a; #include <stdio.h> #include <string.h> /* 当在格式字符串中使用 %*[^:] 时&#xff0c;它表示在读取输入时跳过冒号 : 之前的任何字符。 %*&#xff1a;星号 * 表示读…

DeepMind发布多任务机器人RoboCat;沧海拾珍之LLM、GPT

&#x1f989; AI新闻 &#x1f680; DeepMind发布多任务机器人控制AI模型RoboCat 摘要&#xff1a;谷歌旗下DeepMind发布了名为RoboCat的AI模型&#xff0c;该模型可以控制不同机器人手臂执行多项任务。RoboCat是第一个能够解决和适应多种任务的模型&#xff0c;并且使用真实…

过滤器-filter

1 Servlet规范中的过滤器-Filter 1.1 过滤器入门 1.1.1 过滤器概念及作用 过滤器——Filter&#xff0c;它是JavaWeb三大组件之一。另外两个是Servlet和Listener。 它是在2000年发布的Servlet2.3规范中加入的一个接口。是Servlet规范中非常实用的技术。 它可以对web应用中…

CSS3新增了哪些新特性?

一、是什么 css&#xff0c;即层叠样式表&#xff08;Cascading Style Sheets&#xff09;的简称&#xff0c;是一种标记语言&#xff0c;由浏览器解释执行用来使页面变得更美观 css3是css的最新标准&#xff0c;是向后兼容的&#xff0c;CSS1/2的特性在CSS3 里都是可以使用的…

最优化方法(基于lingo)之 求解线性规划问题(1/6)

一、实验目的&#xff1a; 1. 会建立合理的规划模型&#xff1b; 2. 学习掌握Matlab中求解线性规划的命令&#xff1b; [x,fval]linprog(f,A,b); [x,fval]linprog(f,A,b,Aeq,beq); [x,fval]linprog(f,A,b,Aeq,beq,lb;ub); 3. 要求学生能在计算机上应用各种优化软件包熟练地操作…

音视频流媒体开发工作机会占80%的市场份额

音视频流媒体开发领域的工作机会在过去几年中确实呈现出了快速增长的趋势。随着互联网的普及和网络带宽的提高&#xff0c;人们对音视频内容的需求也越来越大&#xff0c;这导致了许多公司和组织寻求音视频流媒体开发人员来满足市场需求。 音视频流媒体开发工作的主要流程可以概…

对MVVM和MVC开发模式的理解

对MVVM和MVC开发模式的理解 1、MVVM2、MVC3、MVVM与MVC的区别 1、MVVM MVVM最早由微软提出来&#xff0c;它借鉴了桌面应用程序的MVC思想&#xff0c;在前端页面中&#xff0c;把Model用纯JavaScript对象表示&#xff0c;View负责显示&#xff0c;两者做到了最大限度的分离&am…

基于 SpringBoot 2.X 框架的智能制造云办公系统,已开源

简介 基于SpringBoot 2.X框架的智能制造云办公系统&#xff0c;立志打造ERP生产功能的软件&#xff0c;专注进销存财务功能生产管理&#xff0c;适合各行业。主要完成从下单->进货->生产->出库的过程&#xff0c;涉及到领料&#xff0c;出入库&#xff0c;工序&#…

Kotlin Multiplatform项目探索之KMChat

Kotlin Multiplatform项目探索之KMChat 这是当前在 Kotlin Multiplatform 官方文档中提议的用例结构。Kotlin Multiplatform 中包含的许多子组件已经发布了稳定版本&#xff0c;即使目前不稳定的组件也在迅速更新。 本文中的演示项目包括 Compose Multiplatform - Web (Experi…

【微服务架构设计和实现】4.9 微服务测试和部署最佳实践

往期回顾&#xff1a; 第一章&#xff1a;【云原生概念和技术】 第二章&#xff1a;【容器化应用程序设计和开发】 第三章&#xff1a;【基于容器的部署、管理和扩展】 第四章&#xff1a;【4.1 微服务架构概述和设计原则】 第四章&#xff1a;【4.2 服务边界的定义和划分…

STM32单片机(六)TIM定时器 -> 第二节:TIM定时中断练习2(定时器外部时钟)

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

如何看待社交媒体的时间管理和沉迷问题?

在当今数字化时代&#xff0c;社交媒体已经成为了人们生活中不可或缺的一部分。然而&#xff0c;社交媒体的普及也带来了一个问题&#xff1a;时间管理和沉迷。本文将从多个角度对社交媒体的时间管理和沉迷问题进行分析&#xff0c;并探讨如何合理利用社交媒体并避免沉迷。 第…

【计算机视觉】DINO

paper&#xff1a;Emerging Properties in Self-Supervised Vision Transformers 源码&#xff1a;https://github.com/facebookresearch/dino 20230627周二目前只把第一部分看完了。 论文导读&#xff1a;DINO -自监督视觉Transformers - deephub的文章 - 知乎、 DINO原理…

C生万物 | 细说动态内存管理【附经典笔试题】

文章目录 一、为什么存在动态内存分配二、动态内存函数的介绍1、malloc和free2、calloc3、reallocrealloc扩容机制&#xff1a;【本地扩容】和【异地扩容】实际应用&#xff1a;数据结构之【顺序表】与【顺序栈】 三、常见的动态内存错误1、对NULL指针的解引用操作2、对动态开辟…

Redisson源码-多线程之首个获取锁的线程加解锁流程

Redisson源码-多线程之首个获取锁的线程加解锁流程 简介 当有多个线程同时去获取同一把锁时&#xff0c;第一个获取到锁的线程会进行加解锁&#xff0c;其他线程需订阅消息并等待锁释放。 以下源码分析基于redisson-3.17.6版本&#xff0c;不同版本源码会有些许不同需注意。 …

数据结构--单链表的插入删除

数据结构–单链表的插入&删除 目标 单链表的插入&#xff08;位插、前插、后插&#xff09; 单链表的删除 单链表的插入 按为序插入(带头结点) ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。 思路&#xff1a;找到第i-1个结点,将新结点插入其…

软件工程期末报告(登录注册部分)

云小智微校园工具系统的设计与实现成员1注册模块 第一章 绪论 系统的背景描述和概述&#xff1a;可以描述系统服务的对象是学生,满足他们查询课程安排和上课时间的需求。目前市场上确实存在这方面的需求,这款app可以方便学生管理课程。系统采用客户端-服务器架构,运行在安卓平…

自学黑客(网络安全),一般人我劝你还是算了吧(自学网络安全学习路线--第十章 公钥基础设施-PKI)【建议收藏】

文章目录 一、自学网络安全学习的误区和陷阱二、学习网络安全的一些前期准备三、自学网络安全学习路线一、PKI概述1、理论基础2、PKI提供的安全服务 二、数字证书1、数字证书的格式2、数字证书的生命周期3、用JAVA工具生成数字证书 三、PKI组成四、PKI功能五、信任模型六、相关…

基于 Redis 手写一个“秒杀”

博主介绍&#xff1a; ✌博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家✌ Java知识图谱点击链接&#xff1a;体系化学习Java&#xff08;Java面试专题&#xff09; &#x1f495;&#x1f495; 感兴趣的同学可以收…