精选算法入门——day2

精选算法入门——day2

  • 题目一
    • 题干
    • 解题思路一
    • 解题思路二
    • 解题思路三
    • 思路三代码
  • 题目二
    • 题干
    • 解题思路
    • 代码
  • 题目三
    • 题干
    • 解题思路一
    • 代码
    • 解题思路二
    • 代码
    • 解题思路三
    • 代码
  • 题目四
    • 题干
    • 解题思路
    • 代码

题目一

题干

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组
{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

解题思路一

拿到这条题目自然想到统计每个数字,通过每个数字出现的次数来判断是否超过数组长度的一半,那么我们可以借用map这个数据结构,所谓的map就是键值对,键就是数组中的元素,值就是每个元素出现的次数,通过遍历整个数组将每个数组中的元素记录下来,最后比较每个元素出现的次数与数组长度一般的关系。这种方法当然可以,但是我们借用了map,不免会造成更多的空间复杂度。

解题思路二

我们可以先进行排序,那么如果真的存在超过数组长度的数,那么一定是在数组的中央,比如:
在这里插入图片描述
从图中我们可以看到,如果从最左边开始就是目标值,那么中间位置就是我们要找的数字(第一个图);如果是最右边开始就是目标值,那么中间位置也是我们要找的数字(第二个图);如果从中间某个位置开始,那么中间位置也是我们要找的数字(第三个图);但是并不是中间数就是一定满足条件的,比如,第四个图,虽然在中间位置,但是并不符合要求,所以我们找到中间位置后,通过遍历一遍数组对中间数字出现的个数进行统计,统计完在与数组长度的一半进行对比,如果大于则符合要求,如果小于则不符合要求。

解题思路三

目标条件:目标数据超过数组长度的一半。那么对数组,我们同时去掉两个不同的数字,到最后剩下的一个数就是 该数字。如果剩下两个,那么这两个也是一样的,就是结果,在其基础上把最后剩下的一个数字或者两个回到原来数组中, 将数组遍历一遍统计一下数字出现次数进行最终判断。那么具体怎么做呢?我们可以先将第一个数字记下来当作目标值(target),并把他出现的个数(times)记为1,然后向后遍历,如果出现与target相同的数字那么就将times+1,如果出现不同的数字就将times-1,当times出现为0时就将下一个数组当作target,并将times更新为1。在遍历完这个数组的时候,target就是出现次数最多的值(PS:但不一定是目标值),因此我们需要对整个数组进行遍历,对target出现次数进行统计。我们看具体的例子:
在这里插入图片描述
首先我们将1记为target,并把times记为1,向后遍历后发现2与target(1)不同,那么times-1,此时times为0,那么把后面一个数字(3)记为target,并把times记为1,再向后遍历,发现2与现在的target(3)不同,那么times-1,此时times为0,再把后面一个数字(2)记为target,并把times记为1,向后遍历,发现与target(2)相同,那么times+1,此时times为2,继续向后遍历,后面出现分别是5和4,times变为了0,此时将最后一个数字2记为target,times记为1,遍历结束,这里target就是此数组中出现次数最多的出现,这时候在进行一次遍历,将2出现的个数统计出来,并于数组长度的二分之一进行比较,得出结果,数字2就是我们要找的目标数值。

思路三代码

import java.util.*;
public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param numbers int整型一维数组 * @return int整型*/public int MoreThanHalfNum_Solution (int[] numbers) {// write code hereif (numbers == null || numbers.length == 0){return 0;}int target = numbers[0];int times = 1;for(int i = 1; i < numbers.length; i++){if(times==0){target = numbers[i];times = 1;}if(target == numbers[i]){times++;}else{times--;}}times = 0;for(int i = 0;i<numbers.length;i++){if(target == numbers[i]){times++;}}return times > (numbers.length/2)? target:0;}
}

题目二

题干

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字
符串为We%20Are%20Happy。

解题思路

这条题目还是比较简单的,我们可以看到空格被替换成了“%20”,也就是说一个字符(空格是一个字符),被替换成了三个字符(‘%’,‘2’,‘0’),那么我们可以先统计空格的个数,通过空格的个数计算出新的字符串长度(老字符串长度+2×空格的个数),然后一个指针指向新字符串的最后一个位置,一个指针指向老字符串的最后一个位置,两个指针同时先前遍历,遍历过程中也将老字符串指针指向的字符赋值给新字符串指针,当老字符串指向空格时,把他替换成“%20”(PS:这里需要注意,因为是从后向前遍历,并且是一个一个的赋值,那么应该是先赋值“0”,然后是“2”,最后时“%”),直到两个指针完成遍历。这个题目我就不在画图了,直接上代码。

代码

public class Solution {public static String replaceSpace(StringBuffer str) {int count = 0;for (int i = 0; i < str.length(); i++) {if (str.charAt(i) == ' ') {count++;}}int old_end = str.length() - 1;int new_length = str.length() + 2 * count;int new_end = new_length - 1;str.setLength(new_length);while (new_length >= 0 && old_end >= 0) {if (str.charAt(old_end) == ' ') {str.setCharAt(new_end, '0');new_end--;str.setCharAt(new_end, '2');new_end--;str.setCharAt(new_end, '%');new_end--;old_end--;} else {str.setCharAt(new_end,str.charAt(old_end));new_end--;old_end--;}}return str.toString();}public static void main(String[] args) {StringBuffer str = new StringBuffer("We Are Happy.");;System.out.println(replaceSpace(str));}
}

题目三

题干

输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

解题思路一

这个题目是一个非常典型的题目,有很多种方法,在这我们介绍三种,第一种,引入栈,我们知道栈是先进后出,通过将遍历的每个元素按顺序放入栈中,在把每个栈中的元素弹出来,那么就能够完成,这里也不再举具体的例子了,直接上代码。

代码

import java.util.*;
/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*
*/
import java.util.ArrayList;
public class Solution {public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {ArrayList<Integer> list = new ArrayList<>();if(listNode == null){return list;}Stack<Integer> stack = new Stack<>();while(listNode != null){stack.add(listNode.val);listNode = listNode.next;}while(!stack.isEmpty()){list.add(stack.pop());}return list;}
}

解题思路二

我们在原来遇到数组逆置的时候是通过双指针进行逆置,也就是说前一个指针跟后一个指针所指向的内容进行交换,前指针往后,后指针往前,直到两个指针相碰。但是单链表不行,原因就在于所谓的后指针无法往前移动,前面的节点可以往后找,但是后面的节点无法往前找。因此我们自然就想到一个思路,我们先将链表转化为数组,然后利用数组进行逆置。这个我们也不举例子了,直接上代码。

代码

import java.util.*;
/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*
*/
import java.util.ArrayList;
public class Solution {public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {ArrayList<Integer> list = new ArrayList<>();if(listNode == null){return list;}while(listNode!=null){list.add(listNode.val);listNode = listNode.next;}int i = 0;int j = list.size() - 1;while(i < j){int tmp = list.get(i);list.set(i,list.get(j));list.set(j,tmp);i++;j--;}return list;}
}

解题思路三

我们可以采用递归的方式来解决这个问题。我们假设有一个链表,我们要逆序打印每个节点,那么第一个节点是最后一个打印,也就意味着我要打印第一个,那么我要把后面所有顺序的节点都打印了,而第二个节点我要打印,也就是除了第一个节点把后面所有顺序的节点都打印了,以此类推,那么到最后一个节点,也就是最先打印节点,那么很明显这个是可以看作一个递归问题的。也就是一直往下递归,递归到最后一个节点,打印,然后出递归,打印……我们用例子理解一下。
在这里插入图片描述
比如现在我们要逆序打印:1 2 3,那么我们先进入第一层递归(1),我们发现1后面还有节点,那么进入第二层递归(2),我们发现2后面还有节点,那么进入第三层递归(3),我们发现后面没用节点了,那么就打印该节点(3),出递归,打印节点(2),出递归,打印节点(1),递归结束。如此一来打印的顺序就是3,2,1。这就是用递归解决这道问题的思路,我们上代码。

代码

import java.util.*;
/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*
*/
import java.util.ArrayList;
public class Solution {public void function (ListNode listNode,ArrayList<Integer> list){if(listNode == null){return;}function(listNode.next,list);list.add(listNode.val);}public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {ArrayList<Integer> list = new ArrayList<>();function(listNode,list);return list;}
}

题目四

题干

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

解题思路

这条题目难度就相对于上面几道题就会难上许多,首先我们要先了解如何通过前序和后序遍历手写出二叉树。我们举个例子:
在这里插入图片描述
我们复习回顾一下二叉树的遍历方式:

前序遍历:根→左子树→右子树
中序遍历:左子树→根→右子树
后续遍历:左子树→右子树→根

由此我们可以知道前序遍历中第一个数字就是整个树中的根节点,那么在中序遍历中,就可以通过根分为左右两边,如图所示:
在这里插入图片描述
从图中我们可以看到根节点把原始的中序变为了左子树的中序和右子树的中序,而在前序当中,也有对应左子树的前序和对应右子树的前序,如图所示:
在这里插入图片描述
那么我们又可以根据左子树的前序和中序(前序:2485;中序:8425),以及右子树的前序和中序(前序:367;中序:637)进行进一步划分,以此类推,直到划分完,因此我们仍然可以用递归的方法来解决这个问题,也就是说首先利用前序的第一个节点划分中序的左右子树,根据左右子树的中序节点的个数,来确定前序遍历中对应的左右子树的前序节点的个数,那么我们就把求一整棵树的问题划分求左右子树的问题(可能有些拗口,可以对照着上面的图来理解)。我们来看代码的实现。

代码

import java.util.*;/** public class TreeNode {*   int val = 0;*   TreeNode left = null;*   TreeNode right = null;*   public TreeNode(int val) {*     this.val = val;*   }* }*/public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param preOrder int整型一维数组 * @param vinOrder int整型一维数组 * @return TreeNode类*/public TreeNode function(int[] preOrder,int pre_start,int pre_end, int[] vinOrder,int vin_start, int vin_end){if(pre_end<pre_start||vin_end<vin_start){return null;}TreeNode root = new TreeNode(preOrder[pre_start]);for(int i = vin_start;i <= vin_end;i++){if(preOrder[pre_start] == vinOrder[i]){root.left = function(preOrder,pre_start+1,pre_start+i-vin_start,vinOrder,vin_start,i-1);root.right = function(preOrder,pre_start+i-vin_start+1,pre_end,vinOrder,i+1,vin_end);break;}}return root;}public TreeNode reConstructBinaryTree (int[] preOrder, int[] vinOrder) {// write code hereif(preOrder.length==0||vinOrder.length==0||preOrder.length!=vinOrder.length){return null;}return function(preOrder,0,preOrder.length-1,vinOrder,0,vinOrder.length-1);}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PDF转换为TIF,JPG的一个简易工具(含下载链接)

目录 0.前言&#xff1a; 1.工具目录 2.工具功能&#xff08;效果&#xff09;&#xff0c;如何运行 效果 PDF转换为JPG&#xff08;带颜色&#xff09; PDF转换为TIF&#xff08;LZW形式压缩&#xff0c;可以显示子的深浅&#xff09; PDF转换为TIF&#xff08;CCITT形…

uniapp+Android智慧居家养老服务平台 0fjae微信小程序

目录 项目介绍支持以下技术栈&#xff1a;具体实现截图HBuilderXuniappmysql数据库与主流编程语言java类核心代码部分展示登录的业务流程的顺序是&#xff1a;数据库设计性能分析操作可行性技术可行性系统安全性数据完整性软件测试详细视频演示源码获取方式 项目介绍 老年人 登…

IDEA:Properties in parent definition are prohibited

问题背景 如果你在POM.xml中使用了自定义版本&#xff0c;那么IDEA就没办法很动态检测&#xff08;其实可以做到的&#xff0c;不是吗&#xff09;&#xff0c;就会有一个Properties in parent definition are prohibited 的错误信息&#xff08;禁止使用父级定义中的属性&…

吊打ChatGPT4o!大学生如何用上原版O1辅助论文写作(附论文教程)

目录 1、用ChatGPT生成论文选题2、用ChatGPT生成论文框架3、用ChatGPT进行文献整理4、用ChatGPT进行论文润色5、用ChatGPT进行问题求解6、用ChatGPT进行思路创新7、用ChatGPT进行论文翻译8、如何直接使用ChatGPT4o、o1、OpenAI Canvas 9、OpenAI Canvas增强了啥&#xff1f;10、…

打造自己的RAG解析大模型:Windows部署OCR服务(可商业应用)

在上一篇文章中&#xff0c;我们介绍了如何在 Windows 环境中配置 OCR 相关模型&#xff0c;并完成了模型验证。本篇文章将基于之前的内容&#xff0c;进一步讲解如何将文本检测、方向分类和文本识别模型进行串联&#xff0c;最终搭建一个基础的 OCR 应用服务。通过这些模型的串…

降重秘籍:如何利用ChatGPT将重复率从45%降至10%以下?

AIPaperGPT&#xff0c;论文写作神器~ https://www.aipapergpt.com/ 重复率高达45%&#xff1f;很多人一查论文的重复率&#xff0c;瞬间想“完了&#xff0c;这次真的要重写了”。但其实不用这么绝望&#xff01;有了ChatGPT&#xff0c;降重真的没那么难。今天就教你几招&a…

网络安全概述:从认知到实践

一、定义 网络安全&#xff0c;即致力于保护网络系统所涵盖的硬件、软件以及各类数据&#xff0c;切实保障其免遭破坏、泄露或者篡改等不良情形的发生。 二、重要性 个人层面&#xff1a;着重于守护个人隐私以及财产安全&#xff0c;为个人在网络世界中的各项活动提供坚实的保…

日语发音

中文 阴平&#xff08;第一声&#xff09;&#xff0c;用“ˉ”表示&#xff0c;如lā&#xff1b;阳平&#xff08;第二声&#xff09;&#xff0c;用“ˊ”表示&#xff0c;如l&#xff1b;上声&#xff08;第三声&#xff09;&#xff0c;用“ˇ”表示&#xff0c;如lǎ&am…

pWnos1.0 靶机渗透 (Perl CGI 的反弹 shell 利用)

靶机介绍 来自 vulnhub 主机发现 ┌──(kali㉿kali)-[~/testPwnos1.0] …

个人网站,怎么操作才能提升个人网站的流量

运营个人网站以提升流量是一个综合性的过程&#xff0c;涉及内容优化、技术调整、用户体验提升以及外部推广等多个方面。以下是一些专业建议&#xff0c;旨在帮助个人网站运营者有效提升网站流量&#xff1a; 1.精准关键词研究与优化 -关键词研究&#xff1a;利用工具如谷歌…

MATLAB图像去雾系统

应用背景 现在工业发展迅速&#xff0c;产生的废气很严重&#xff0c;导致雾霾厉害&#xff0c;现在虽然有硬件来拍摄&#xff0c;可以清晰化视野&#xff0c;但是硬件成本昂贵&#xff0c;急需寻求一种算法来帮助雾霾的清晰处理。显得经济。 采用算法原理 本文采用全局直方…

基金好书入门阅读笔记《基金作战笔记:从投基新手到配置高手的进阶之路》2

买基金&#xff0c;说到底是买基金所持有的一揽子资产。那么&#xff0c;常见的可投资产都有哪些类型呢&#xff1f; 图2.9进行了系统性的梳理&#xff0c;我们把资产分为四大类&#xff0c;分别是权益类、固收类、现金和另 类&#xff0c;下面就一一解读。 年化收益率是把一段…

Flume实战--Flume中的拦截器详解与操作

在处理大规模数据流时&#xff0c;Apache Flume 是一款功能强大的数据聚合工具&#xff0c;它可以通过拦截器在运行时对Event进行修改或丢弃。本文将详细讲解Flume中的拦截器&#xff0c;包括时间戳拦截器、Host添加拦截器、静态拦截器以及如何自定义拦截器。 Flume入门到实践…

Centos怎么执行脚本

方法一&#xff1a;切换到shell脚本所在的目录&#xff08;此时&#xff0c;称为工作目录&#xff09;执行shell脚本 cd /data/shell ./hello.sh 方法二&#xff1a;以绝对路径的方式去执行bash shell脚本 /data/shell/hello.sh 方法三&#xff1a;直接使用bash 或sh 来执行…

VGG原理与实战

VGG网络结构 这也更好的块状结构,256个卷积核 卷积就是我们的一个特征图啊往往都会缩小 &#xff0c;然后的话但它通道不会变.卷积一般是使用我们的通道C变大,磁化但是它的通道就是我们那个H和W一般都会变小.下采样的意思就是使分辨率变小 vgg—block内的卷积层都是同结构的意…

vite学习教程04、vue集成axios封装request工具类及应用

文章目录 前言1、安装axios2、封装request工具类3、封装api请求工具4、实战&#xff1a;vue中使用api请求工具类资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝3W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技…

k8s 中存储之 hostPath 卷

目录 1 hostPath 卷介绍 2 hostPath 卷实际应用操作 2.1 创建 pod 资源类型 2.2 修改清单文件增加 hostPath 对应的参数配置 2.3 查看是否创建 卷 和 pod 2.4 创建发布文件测试是否正常访问 1 hostPath 卷介绍 EmptyDir中数据不会被持久化&#xff0c;它会随着Pod的结束而销…

【数据结构】【链表代码】随机链表的复制

/*** Definition for a Node.* struct Node {* int val;* struct Node *next;* struct Node *random;* };*/typedef struct Node Node; struct Node* copyRandomList(struct Node* head) {if(headNULL)return NULL;//1.拷贝结点&#xff0c;连接到原结点的后面Node…

【工欲善其事】巧用 Sublime Text 生成带格式的 HTML 片段

文章目录 【工欲善其事】巧用 Sublime Text 生成带格式的 HTML 片段1 问题由来2 操作流程步骤1&#xff1a;打开代码片段定制页步骤2&#xff1a;在新标签页输入定制 XML步骤3&#xff1a;保存定义内容步骤4&#xff1a;功能测试 3 拓展 【工欲善其事】巧用 Sublime Text 生成带…

【Python】wxPython 高 DPI 缩放问题(笔记本上字体模糊问题)

问题 使用 wxPython 编写的程序在某些高 DPI 的电脑&#xff08;通常是笔记本&#xff09;上显示出来的字体会非常模糊&#xff1a; 事实上 wxPython 是支持高 DPI 的&#xff0c;但是由于我们的程序没有显式指明支持高 DPI&#xff0c;因此系统默认不支持高 DPI&#xff0c;…