精选算法入门——day3

news2024/11/28 23:44:48

精选算法入门——day3

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

题目一

题干

大家都知道斐波那契数列,现在要求输入一个正整数 n ,请你输出斐波那契数列的第 n 项。斐波那契数列的表达式如下图:
在这里插入图片描述

解题思路一

这条题目属于经典中的经典了,我们用表达式可能不太清楚,我们用表格来表示:

项数斐波那契数
11
21
32
43
…………

也就是说第n项的结果是由第n-1项和第n-2项相加得到的,就比如第四项的结果是3,它是由第三项(2)与第二项(1)相加得到的。那么我们可以用迭代的方式来解决这个问题,具体计算如图所示:
在这里插入图片描述
首先我们将first和second都赋值为1,然后将first(1)+second(1)相加得到third(2),然后再将second赋值给first,再把third赋值给second,再将first(1)+second(1)相加得到third(3),以此类推。但是需要注意的是循环的次数,如果n=3,就循环一次,n=4,就循环两次,因此我们可以设置while(n>2),当然我们还有一个问题,我们的返回值肯定是third这个毋庸置疑,但是我们也要考虑n=1和n=2的情况,我们直到n=1和n=2,返回值都应该是1,那么我们可以将third初始化为1。下面是完整代码:

代码

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int整型 
     * @return int整型
     */
    public int Fibonacci (int n) {
        // write code here
        int first = 1;
        int second = 1;
        int third = 1;
        while(n > 2){
            third = first + second;
            first = second;
            second = third;
            n--;
        }
        return third;
    }
}

解题思路二

这道题还有没有其他的解题思路呢?当然有,我们看下面这个图:
在这里插入图片描述
从图中可以看到,我们求f(5),就需要求f(4)和f(3),求f(4)就需要求f(3)和f(2),直到最后为f(1)和f(2),因此我们将一个大的问题分为了小问题,再将小问题再化为小小问题,因此我们可以采用递归来解决这个问题。下面是完整代码:

代码

import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int整型 
     * @return int整型
     */
    public int Fibonacci (int n) {
        if(n <= 2){
            return 1;
        }
        return Fibonacci(n-1) + Fibonacci(n-2);
    }
}

解题思路三

有同学要说,这个代码少,看着简洁,肯定是一个好的方法,但事实是这样吗?其实不然,这种方法存在一个弊端,为什么这么说,从上面的图我们可以发现,单单的f(3)就被求了两次,一次是求f(4)(f(4)=f(3)+f(2))时,一次是求f(5)(f(5) = f(4)+f(3))时,就相当于不停的重复计算,这样一来时间复杂度就增加了,那么有什么好的方法嘛?我们可以想象一下,当我们记不住事的时候,我们怎么办?有同学要说,拿笔记下来不就行了?确实是这样的,我们也可以用这种思想,我们可以定义一个map,比如说求n=5,我们就到map里面去找,有没有n=4和n=3的结果,如果有,就把两者相加,没有就计算n=4(n=3),计算完n=4(n=3)后,再把n=4(n=3)的结果记录到map里面。下面为完整代码:

代码

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int整型 
     * @return int整型
     */
    private Map<Integer,Integer> map = new HashMap<>();
    public int Fibonacci (int n) {
        if(n <= 2){
            return 1;
        }
        int pre = 0;
        if(map.containsKey(n-1)){
            pre = map.get(n-1);
        } else {
            pre = Fibonacci(n-1);
            map.put(n-1,pre);
        }
        int ppre = 0;
        if(map.containsKey(n-2)){
            ppre = map.get(n-2);
        } else {
            ppre = Fibonacci(n-2);
            map.put(n-2,ppre);
        }
        return pre+ppre;
    }
}

题目二

题干

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算
不同的结果)。

解题思路

青蛙🐸跳台阶也算得上一个经典的问题了,这个问题我专门做过一篇博客,链接如下:青蛙跳台阶问题(Java语言),这一次我们重新审视一下这个问题。
在这里插入图片描述
我们假设青蛙🐸已经在第n个台阶了,那么我们知道,此青蛙🐸是从n-1个台阶跳一格到第n个台阶,或者从第n-2个台阶跳两格到第n个台阶,因此我们可以得到f(n) = f(n-1) + f(n-2),也就是说,青蛙跳到第n个台阶的总跳法数=第n-1个台阶的总跳法数+第n-2个台阶的总跳法数。我们再来看一下这个式子:f(n) = f(n-1) + f(n-2),是不是很熟悉,没错,就是我们上面的斐波那契数列。那么我们就只需要确定f(1)和f(2)就可以了,青蛙🐸跳上第一个台阶有一种跳法,青蛙🐸跳上第二个台阶有两种跳法,也就是说f(1)=1,f(2) = 2。具体的代码我也不再写了。

题目三

题干

我们可以用 2×1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个 2×1 的小矩形无重叠地覆盖一个 2×n 的大矩形,总共有多少种方法?比如:n=3时, 2×3 的矩形块有3种覆盖方法:
在这里插入图片描述

解题思路

这道题拿到手上感觉很简单,其实也是无从下手的感觉,那么我们应该如何解决这类问题呢?我们画个图理解一下:
在这里插入图片描述
我们假设覆盖一个 2×n 的大矩形,共有f(n)种方法,也就是图中左边的样子,我们可以把f(n)拆分为右边两种,也就是覆盖2×(n-1)的大矩形(它的左边竖着放一个小矩形)的方法数和覆盖2×(n-2)的大矩形的方法数(它的左边横着放两个小矩形),有同学要问下面这个方法不是可以竖着放两个小矩形嘛?这样是不行的,为什么不行呢?我们看当我们竖着放的时候,其实就和上面(n-1)的重复了,由此我们总结f(n) = f(n-1)+f(n-2)。耶?这个好像还是斐波那契数列,那么我们再看他的初始情况,当n=1时,f(n)=1,当n=2时,f(n)=2,由此问题解决,具体的代码部分也不再详细写出来了。

题目四

题干

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

解题思路一

这条题目拿到手,第一感觉是将该数和1进行按位与操作,然后再将1左移一位,直到循环结束。我们通过画图来理解:
在这里插入图片描述
上面的数字为输入的数字(n),下面的数字为移动的数字(初始为1),当n和1进行按位与操作时,如果等于1那么证明二进制中存在一个1,那么计数器count++,并且数字1左移一位。如果n和1(左移后数字不是1了,这里为了方便理解就还说是1)进行按位与操作时等于0,那么证明该二进制位置不是数字1,计数器不变,数字1左移一位,直到循环结束,下面是完整代码。

代码

import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int整型 
     * @return int整型
     */
    public int NumberOf1 (int n) {
        // write code here
        int count = 0;
        int a = 1;
        for(int i=0; i<32; i++){
            if((a&n) != 0){
                count++;
            }
            a = a<<1;
        }
        return count;
    }
}

解题思路二

我们发现在解题思路一中好是好,但是有一个问题,什么问题?我们发现,不管n这个数的二进制位上是0还是1,移动的数字都要左移,当二进制中0很多1很少的时候效率就很低,因为我们要找的是二进制位上的1,0是我们做的无用功,就好比说,老板布置一个任务给你,这个任务麻烦多(0多),好处少(1少),但是你又不得不干,那肯定很烦呀。那么还有什么方法嘛?我们直接上图:
在这里插入图片描述
我们可以看到初始输入n为1100 0011,此时计算n和n-1按位与操作,得到结果1100 0010,此时我们把这个新的结果赋值给n,如此循环,循环一次,计数器count就+1,问题就解决了,有同学会问为什么呢?我们直到一个数减去1,就要往前面借一个1,并且所借1后面的所有数字都要取反(例如:1000 0000,减去1后,他的最左边的1被借走了,并且后面的数字全部取反,也就是0111 1111),那么按位与操作就相当于把所借的“1”给消除掉,循环了几次,也就消除了几个“1”,那么就能够得到结果了。下面为完整代码:

import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int整型 
     * @return int整型
     */
    public int NumberOf1 (int n) {
        // write code here
        int count = 0;
        while(n != 0){
            n = n & (n-1);
            count++;
        }
        return count;
    }
}

题目五

题干

输入一个链表,输出该链表中倒数第k个结点。

解题思路一

这道题目的难点就在于,在单链表的情况下如何输出链表中倒数第k个节点,我们直到单链表只能由前往后,无法由后往前,有一个非常简单的思路,首先我们遍历整个链表,并记下链表的长度,然后由倒数求出整数多少个。这个思路比较简单我们就不画图解决了,我们直接上代码:

代码

    public ListNode function(ListNode head, int k) {
        if (head == null){
            return null;
        }
        int count = 0;
        ListNode tmp = head;
        while (tmp != null) {
            count++;
            tmp = tmp.next;
        }
        int key = count - k;
        for (int i = 0; i < key; i++) {
            head = head.next;
        }
        return head;
    }

解题思路二

当然我们也可以用快慢指针的方法来解决,什么意思?我们通过画图来理解一下:
在这里插入图片描述
例如当我们求倒数第二个节点时,我们可以先让fast指针先走一格,然后fast和slow同时走,当fast指针到达终点的时候,slow指针就是我们求的节点,为什么呢?其实道理很简单,我们要求倒数第k个节点,那么它距离最后一个节点的距离是k-1,也就可以让一个指针(fast)先走k-1个位置,在让slow和fast一起走,最后fast到达最后一个节点,那么slow也就到了。下面我们通过代码来实现。

代码:

public ListNode function(ListNode head, int k) {
        if (head == null){
            return null;
        }
        ListNode fast=head;
        ListNode slow=head;
        for (int i = 0; i <k-1; i++) {
            fast = fast.next;
        }

        while (fast.next!=null){
            fast=fast.next;
            slow=slow.next;
        }
        return slow;
    }

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

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

相关文章

尚雷仕(湖北)健康科技公司5.98MW分布式光伏10KV并网系统应用

1.概述 我国正致力于实现“双碳”目标&#xff0c;新能源装机容量正快速增长&#xff0c;电力系统正在经历向高比例新能源系统的转型。然而&#xff0c;分布式光伏的接入也带来了挑战&#xff0c;例如电能质量的下降和供电可靠性的不足。尽管如此&#xff0c;光伏发电依然具有…

Java的IO操作与文件的基本常识

首先什么是IO操作呢? IO操作其实解释操作硬盘 1. 文件系统操作 创建文件,删除文件,重命名文件,创建目录…操作 2. 文件内容操作 进行读与写操作 先来了解一下基本的文件知识方便学习接下来的IO操作 文件路径 文件路径是从数根节点触发,沿着树杈一直往下走,到达目标文件…

github——指标统计

github——指标统计 它的作用特定项目统计首页展示 github-readme-stats是一个可以统计指定用户github指标的项目。可以使用此项目统计自己的github&#xff0c;用于首页展示。效果如图&#xff1a; 它的作用 它可以&#xff1a; 统计git操作统计账户编程语言构成比例解除githu…

ThingsBoard规则链节点:Delete Keys节点详解

引言 删除键节点简介 用法 含义 应用场景 实际项目运用示例 智能家居系统 工业自动化生产线 车联网平台 结论 引言 ThingsBoard是一个功能丰富的物联网平台&#xff0c;它支持设备管理、数据收集与处理以及实时监控。其核心组件之一是规则引擎&#xff0c;允许用户定义…

杨中科 ASP.NETCORE 异步编程二

一、不要用sleep() 如果想在异步方法中暂停一段时间&#xff0c;不要用Thread.sleep()&#xff0c;因为它会阻塞调用线程&#xff0c;而要用await.Task.Delay()。 举例: 下载一个网址,3秒后下载另一个 示例&#xff1a; sleep() 为了能直观看到效果&#xff0c;使用winfor…

基于springboot vue 三味书屋网络书店销售管理设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm springcloud&#xff09; vue .net php phython node.js uniapp小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次…

【Windows】【DevOps】Windows Server 2022 在线/离线 安装openssh实现ssh远程登陆powershell、scp文件拷贝

服务器在线安装openssh 管理员权限启动powershell&#xff0c;输入指令 查看默认安装状态 Get-WindowsCapability -Online | Where-Object Name -like OpenSSH* 可以看到系统默认安装了客户端&#xff0c;未安装服务器端 安装服务器端 Add-WindowsCapability -Online -Nam…

Spring 循环依赖详解:问题分析与三级缓存解决方案

在Spring框架中&#xff0c;循环依赖&#xff08;Circular Dependency&#xff09;是指多个Bean相互依赖&#xff0c;形成一个循环引用。例如&#xff0c;Bean A依赖于Bean B&#xff0c;而Bean B又依赖于Bean A。这种情况在Bean创建时可能导致Spring容器无法正常完成初始化&am…

一点基础没有可以参加TRIZ创新方法培训吗?

当然可以&#xff0c;即使一点基础都没有&#xff0c;参加TRIZ创新方法培训也是完全可行的。TRIZ理论作为一种系统的创新方法&#xff0c;旨在帮助人们跨越思维定式&#xff0c;高效解决发明创造中的各种问题。本文&#xff0c;天行健六西格玛顾问将详细阐述为何零基础的学员也…

2024年诺贝尔物理学奖2

2024年&#xff0c;诺贝尔物理学奖没有颁给物理学家&#xff0c;而是给了两位计算机科学家&#xff0c;他们发明了神经网络&#xff0c;这项技术是人工智能的基础。这表明物理学和计算机科学的联系越来越紧密。获奖者约翰霍普菲尔德和杰弗里辛顿在神经网络方面做出了巨大的贡献…

探秘纯前端Excel表格:构建现金流量表的完整指南

最新技术资源&#xff08;建议收藏&#xff09; https://www.grapecity.com.cn/resources/ 现金流量表&#xff08;Cash Flow Statement&#xff09;&#xff0c;是指反映企业在一定会计期间现金和现金等价物流入和流出的报表。现金流量表是企业财务报表的三个基本报告之一&…

LeetCode.611有效三角形的个数

题目链接611. 有效三角形的个数 - 力扣&#xff08;LeetCode&#xff09; 1.常规解法&#xff08;会超时&#xff09; 由于构成三角形的条件为两边之和大于第三边&#xff0c;就可以遍历该数组&#xff0c;找到所有满足这个条件的三元组&#xff0c;代码如下&#xff1a; pub…

【排序算法】快速排序、冒泡排序

文章目录 快速排序1.hoare版本&#xff08;左右指针法&#xff09;时间复杂度、空间复杂度分析优化——三数取中法2.挖坑法3.前后指针版本优化&#xff1a;小区间优化快速排序非递归代码——借助栈 冒泡排序时间复杂度 快速排序 1.hoare版本&#xff08;左右指针法&#xff09…

生成式专题的第二节课--DCGAN

一、DCGAN基础概念 DCGAN&#xff08;Deep Convolutional Generative Adversarial Network&#xff0c;即深度卷积生成对抗网络&#xff09;&#xff0c;于2016年提出&#xff0c;是一种深度学习模型&#xff0c;是生成对抗网络&#xff08;GAN&#xff09;的一种变体&#xf…

国产 HDMI 发送芯片,兼容 HDMI1.4b 及 HDMI 1.4b 下的视频 3D 传输格式。

最高分辨率高达 4K30Hz&#xff0c;最高采样率达到 300MHz.支持 YUV 和 RGB 之间的色彩空间转 换&#xff0c;数字接口支持 YUV 以及 RGB 格式输入的 IIS 接口以及 S/PDIF 接口支持高清音频的 传输&#xff0c;其中 S/PDIF 接口既可以兼容IEC61937 标准下的压缩音频传输&#x…

图像增强——传统算法伽马校正实现暗光增强(附Python代码)

&#x1f4aa; 专业从事且热爱图像处理&#xff0c;图像处理专栏更新如下&#x1f447;&#xff1a; &#x1f4dd;《图像去噪》 &#x1f4dd;《超分辨率重建》 &#x1f4dd;《语义分割》 &#x1f4dd;《风格迁移》 &#x1f4dd;《目标检测》 &#x1f4dd;《图像增强》 &a…

OpenSearch迁移方案

一、背景 因业务需要迁移Opensearch 集群&#xff0c;当前集群数据量高达21TB&#xff0c;采用常规工具进行迁移估计不可取&#xff0c;需要使用对象存储做中转&#xff0c;进行OpenSearch数据迁移。 二、OpenSearch迁移方案 前期进行OpenSearch数据迁移调研 序号方案诠释备…

java项目之科研工作量管理系统的设计与实现源码(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的科研工作量管理系统的设计与实现。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 科研工作…

介绍Java

Java简介 Java是一门由Sun公司&#xff08;现被Oracle收购&#xff09;在1995年开发的计算机编程语言&#xff0c;其主力开发人员是James Gosling&#xff0c;被称为Java之父。Java在被命名为“Java”之前&#xff0c;实际上叫做Oak&#xff0c;这个名字源于James Gosling望向…

Basic Pentesting_ 2靶机渗透

项目地址 plain https://download.vulnhub.com/basicpentesting/basic_pentesting_2.tar.gz 修改静态ip 开机按e 输入rw signie init/bin/bash ctrlx 进入编辑这个文件 vi /etc/network/interfaces修改网卡为ens33 保存退出 实验过程 开启靶机虚拟机 ![](https://img-bl…