算法通关村第五关—队栈和Hash的经典问题(白银)

news2025/2/26 22:09:49

 emsp;emsp;emsp队栈和Hash的经典问题

用栈实现队列

栈是先进后出,队列是先进先出,所以可以使用两个栈来实现队列的功能。
LeetCode232:
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、
empty):
截屏2023-11-30 21.18.57.png
思路:
(1)一个栈作为输入栈,支持push操作,一个栈作为输出栈,支持pop和peek操作
(2)每次pop或peek时,如果输出栈为空,则把输入栈的元素弹出并压入输出栈,此时输出栈从栈顶到栈尾的顺序就是队列从队首道队尾的顺序

class MyQueue{
	Deque<Integer>inStack;
	Deque<Integer>outstack;
	public MyQueue(){
		inStack = new LinkedList<Integer>();
		outStack = new LinkedList<Integer>();
	}
	public void push(int x){
		inStack.push(x);
	}
	public int pop(){
		if (outStack.isEmpty()) in2out();
		return outstack.pop();
	}
	public int peek(){
		if (outstack.isEmpty()) in2out();
		return outstack.peek();
	}
	public boolean empty(){
		return instack.isEmpty() && outstack.isEmpty();
	}
	private void in2out(){
		while (!instack.isEmpty()) outstack.push(instack.pop());
	}
}

用队列实现栈

leetcode225:
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop和empty)。
实现MyStack类:
截屏2023-11-30 21.36.40.png
思路:同样,可以使用两个队列来实现栈。为了满足栈道特性,要满足最后入栈道元素位于队列的队首。
那么可以使用queue1用于存储栈内的元素,queue2作为入栈操作的辅助队列。
入栈时,将将元素入队到queue2,然后将queue1的全部元素依次出队后入队到queue2。此时,queue2的前面的元素就是新入栈的元素,再将queue1与queue2互换,则queue1元素即为栈内元素,队头为栈顶
出栈或取栈顶时,取queue1的队头即可
判空时,判断queue1即可

class Mystack{
	Queue<Integer>queuel;
	Queue<Integer>queue2;
	public MyStack(){
		queue1 = new LinkedList<Integer>();
		queue2 = new LinkedList<Integer>();
	}
	public void push(int x){
		queue2.offer(x);
		while (!queue1.isEmpty()) queue2.offer(queue1.poll());
		Queue<Integer>temp queue1;
		queue1 queue2;
		queue2 temp;
	}
	public int pop(){
		return queue1.poll();
	}
	public int top(){
		return queue1.peek();
	}
	public boolean empty(){
		return queue1.isEmpty();
	}
}

n数之和专题

我的LeetCode的第一题就是求两数之和的问题,当时还只会暴力,不会Hash之类的方法,看到题解差点劝退了。
事实上除此之外,还有几个类似的问题,例如LeetCode15三数之和,LeetCode18.四数相加和LeetCode454.四数相加ll等等。我们就集中看一下。

3.1 两数之和

LeetCode1.给定一个整数数组nums和一个整数目标值target,请你在该
数组中找出和为目标值target的那两个整数,并返回它们的数组下标。你
可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里
不能重复出现。你可以按任意顺序返回答案。
截屏2023-12-01 10.46.34.png
这种题用两层for循环时间复杂度太高,不采用
可以利用哈希表,把遍历过的值保存起来,这样只需寻找target-nums[i]在哈希表中是否存在即可

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>(); //创建一个哈希表map
        for (int i = 0; i < nums.length; i++) { //从数组第一个数遍历到最后一个数
            if (map.containsKey(target - nums[i])) return new int[]{map.get(target - nums[i]), i}; //判断 目标值减去当前值 得到的值在哈希表是否存在(一石二鸟,通过一个数找到另一个数),若存在,证明已达到题目的要求,直接返回这两个数的索引位
            else map.put(nums[i], i);// 上面的if不成立,把当前值存入map哈希表中,注意,key保存当前整数值,value保存对应的索引值
        }
        return new int[]{}; //虽然题目保证能找到,但按照语法要求,还是要返回一个int型数组,比如会报错
    }
}

3.2 三数之和

如果将两个数换成三个会怎样呢?
LeetCode15.给你一个包含n个整数的数组nums,判断nums中是否存在三个元素a,b,c,使得a+b+c=0?请你找出所有和为0且不重复的三元组。注意:答案中不可以包含重复的三元组。
截屏2023-12-01 11.07.00.png
本题看似就是两数增加了一个数,但是难度增加了很多,我们可以使用三
层循环直接找,时间复杂度为O(3),太高了,放弃。
也可以使用双层循环+Hash来实现,首先按照第一题两数之和的思路,我们可以固定一个数target,再利用两数之和的思想去map中存取或查找(-1)*target-num[j],但是这样的问题是无法消除重复结果,例如如果输入[-1,0,1,2,-1,-4],返回的结果是[-1,1,0],[-1,-1,2],[0,1,-1],[0,-1,1],[1,-1,0],[2,-1,-],如果我们再增加一个去重方法,将直接导致执行超时。

那这时候,我们就要想其他方法了,这个公认最好的方式是”排序+双指针我们可以先将数组排序来处理重复结果,然后还是固定一位元素,由于数组是排好序的,所以我们用双指针来不断寻找即可求解,代码如下:

class Solution{
	public List<List<Integer>>threeSum(int[]nums){
		int n = nums.length;
		Arrays.sort(nums);
		List<List<Integer>>ans = new ArrayList();
		//枚举a
		for (int first = 0;first < n; first++){
			//需要和上一次枚举的数不相同
			if (first > 0 && nums[first] = nums[first - 1]) continue;
			//C对应的指针初始指向数组的最右端
			int third = n - 1;
			int target = -nums[first];
			//枚举b
			for (int second  = first + 1; second < n; second++){
				//需要和上一次枚举的数不相同
				if (second > first + 1 && nums[second] == nums[second - 1]) continue;
				//需要保证b的指针在c的指针的左侧
				while (second < third && nums[second] + nums[third] > target) --third;

				//如果指针重合,随着b后续的增加
				//就不会有满足a+b+c=0并且b<c的c了,可以退出循环
				if (second == third) break;

				if (nums[second] + nums[third] == target){
					List<Integer>list new ArrayList<Integer>();
					list.add(nums [first]);
					list.add(nums [second]);
					list.add(nums [third]);
					ans.add(list);
				}
			}
		}
		return ans;
	}
}

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

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

相关文章

不可抗力因素包括什么内容

一、《民法典》所称的“不可抗力”&#xff0c;是指不能预见、不能避免并不能克服的客观情况。主要包括以下几种情形&#xff1a; (1)自然灾害、如台风、洪水、冰雹&#xff1b; (2)政府行为&#xff0c;如征收、征用&#xff1b; (3)社会异常事件&#xff0c;如罢工、骚乱。 ​…

【设计模式-4.1】行为型——策略模式

说明&#xff1a;本文介绍设计模式中的行为型设计模式中的&#xff0c;策略模式&#xff1b; 计算器 策略模式属于行为型设计模式&#xff0c;关注对象的行为。例如&#xff0c;目前有一个计算器类&#xff0c;可对两个数进行加减计算&#xff0c;如下&#xff1a; &#xf…

Innodb数据空间占用探索

了解数据存储空间占用&#xff0c;可以更方便我们再企业中对于数据库相关优化做评估。 一、查看当前数据表空间占用信息 首先这里准备一张数据库表约2.3w数据量&#xff1a; CREATE TABLE project (tenantsid bigint(20) NOT NULL DEFAULT 0 COMMENT 租户ID,project_id bigi…

Redis RDB

基于内存的 Redis, 数据都是存储在内存中的。 那么如果重启的话, 数据就会丢失。 为了解决这个问题, Redis 提供了 2 种数据持久化的方案: RDB 和 AOF。 RDB 是 Redis 默认的持久化方案。当满足一定条件的时候, 会把当前内存中的数据写入磁盘, 生成一个快照文件 dump.rdb。Redi…

thinkphp 5.1 对数据库查出来的字段进行预处理

比如数据库的设计是下面这样子&#xff1a; 我想展示的是这个样子&#xff1a; 前端可以处理。 Think PHP的处理方式&#xff1a; 定义属性 &#xff1a; $this->customize 任意值;//这里的之没有作用 <?phpnamespace app\hs\controller\shop;use app\daogou\mo…

C++ list容器

文章目录 C++ list容器list基本概念list构造函数list 赋值和交换list 大小操作list 插入和删除list 数据存取list 反转和排序排序案例C++ list容器 list基本概念 功能:将数据进行链式存储 链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中…

ipvlan介绍

最近使用docker&#xff0c;涉及到需要跨多台物理机部署系统&#xff0c;查了好多资料&#xff0c;最后查到了ipvlan。那什么是vlan&#xff0c;什么又是ipvlan。 交换机层面的vlan&#xff0c;是按802.1Q规范&#xff0c;在链路层中加了4字节的标识vlan的数据&#xff0c;交换…

12.1 二叉树简单题

101. 对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 思路&#xff1a;对称二叉树 有一个特点是以 中左右顺序遍历左子树的结果会等于 中右左顺序遍历右子树的结果…

Linux的基本指令(4)

目录 20.tar指令&#xff08;重要&#xff09;&#xff1a;打包/解包&#xff0c;不打开它&#xff0c;直接看内容 21.bc指令 22.uname –r指令&#xff1a; 23.重要的几个热键[Tab],[ctrl]-c, [ctrl]-d 20.tar指令&#xff08;重要&#xff09;&#xff1a;打包/解包&#…

Hdoop学习笔记(HDP)-Part.08 部署Ambari集群

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

深度学习(四):pytorch搭建GAN(对抗网络)

1.GAN 生成对抗网络&#xff08;GAN&#xff09;是一种深度学习模型&#xff0c;由两个网络组成&#xff1a;生成器&#xff08;Generator&#xff09;和判别器&#xff08;Discriminator&#xff09;。生成器负责生成假数据&#xff0c;而判别器则负责判断数据是真实的还是 f…

cnpm 安装后无法使用怎么办?

问题的原因 cnpm 安装成功&#xff0c;但是却无法使用&#xff0c;一般分为两种情况&#xff0c;一种是提示无法执行命令&#xff0c;另一种是可以执行但是执行时报错&#xff0c;下面分别说明遇到这两种情况的解决方案。 解决方案 问题一&#xff1a;无法执行相关命令 首先…

Docker快速入门(docker加速,镜像,容器,数据卷常见命令操作整理)

Docker本质是将代码所需的环境依赖进行打包运行,而在Docker中最重要的是镜像和容器 镜像:可以简单地理解为每启动一个docker镜像就会占用计算机一个进程,这个进程和另外起的docker镜像的进程是相互独立的,以数据库为例,每个镜像都会copy一份数据库,在他所在的进程中.别的镜像在…

根文件系统构建-对busybox进行配置

一. 简介 本文来学习 根文件系统的制作中&#xff0c;关于 busybox的配置。 本文继上一篇 busybox中文支持的设置&#xff0c;地址如下&#xff1a; 根文件系统构建-busybox中文支持-CSDN博客 二. 根文件系统构建-busybox配置 1. 配置 busybox 与我们编译 Uboot 、 Lin…

DBeaver 社区版(免费版)下载、安装、解决驱动更新出错问题

DBeaver 社区版&#xff08;免费版&#xff09; DBeaver有简洁版&#xff0c;企业版&#xff0c;旗舰版&#xff0c;社区版&#xff08;免费版&#xff09;。除了社区版&#xff0c;其他几个版本都是需要付费的&#xff0c;当然相对来说&#xff0c;功能也要更完善些&#xff…

HashMap源码全面解析

注&#xff1a;本篇文章是在JDK1.8版本源码进行分析。 一、概述 HashMap 是基于哈希表的 Map接口的实现&#xff0c;是以 key-value 存储形式存在&#xff0c;即主要用来存储键值对。 HashMap的类图&#xff1a; HashMap继承抽象类AbstractMap&#xff0c;实现了Map、Clonea…

select选择框里填充图片,下拉选项带图片

遇到一个需求&#xff0c;选择下拉框选取图标&#xff0c;填充到框里 1、效果展示 2、代码 <el-form-item label"工种图标" class"Form_icon Form_label"><el-select ref"select" :value"formLabelAlign.icon" placeholder&…

2023年第十二届数学建模国际赛小美赛B题工业表面缺陷检测求解分析

2023年第十二届数学建模国际赛小美赛 B题 工业表面缺陷检测 原题再现&#xff1a; 金属或塑料制品的表面缺陷不仅影响产品的外观&#xff0c;还可能对产品的性能或耐久性造成严重损害。自动表面异常检测已经成为一个有趣而有前景的研究领域&#xff0c;对视觉检测的应用领域有…

PyQt6 QRadioButton单选按钮控件

​锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计33条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话…

Opencv框选黑色字体进行替换(涉及知识点:selectROI,在控制台输入字体大小,颜色,内容替换所选择的区域)

import cv2 from PIL import Image,ImageDraw,ImageFont import numpy as npimg_path ../img/ img_clean_path ../img_clean/ name xiao_ben suf .pngimg cv2.imread(img_pathnamesuf) cv2.imshow(original, img)# 选择ROI roi cv2.selectROI(windowName"original&q…