CSDN每日一题学习训练——Java版(字符串相乘、子集、删除链表的倒数第 N 个结点)

版本说明

当前版本号[20231112]。

版本修改说明
20231112初版

目录

文章目录

  • 版本说明
  • 目录
  • 字符串相乘
    • 题目
    • 解题思路
    • 代码思路
    • 补充说明
    • 参考代码
  • 子集
    • 题目
    • 解题思路
    • 代码思路
    • 参考代码
  • 删除链表的倒数第 N 个结点
    • 题目
    • 解题思路
    • 代码思路
    • 参考代码

字符串相乘

题目

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

示例 1:

输入: num1 = “2”, num2 = “3”
输出: “6”

示例 2:

输入: num1 = “123”, num2 = “456”
输出: “56088”

说明:

num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。

解题思路

  1. 首先判断输入的两个字符串是否为0,如果是则直接返回"0"。
  2. 获取两个字符串的长度m和n。
  3. 创建一个长度为m+n-1的整数数组intRes,用于存储乘积的结果。
  4. 使用两层循环遍历num1和num2的每一位数字,将它们相乘并累加到intRes数组中对应的位置。
  5. 从intRes数组的末尾开始向前遍历,如果当前位置的值大于等于10,则需要进位。将当前位置的值除以10,并将余数加到前一位上。
  6. 将intRes数组转换为字符串形式,即为最终的乘积结果。

代码思路

  1. 首先判断输入的两个字符串是否为"0",如果是,则直接返回"0",因为任何数与0相乘都等于0。

    // 如果num1或num2为"0",则直接返回"0"
            if (num1.equals("0") || num2.equals("0"))
                return "0";
    
  2. 获取两个字符串的长度m和n,分别表示num1和num2的位数。

    	// 获取num1的长度m
            int m = num1.length();
            // 获取num2的长度n
            int n = num2.length();
    
  3. 创建一个长度为m+n-1的整型数组intRes,用于存储相乘结果的每一位数字。

    // 创建一个长度为m+n-1的整型数组intRes,用于存储相乘结果的每一位数字
            int[] intRes = new int[m + n - 1];
    
  4. 使用两层循环遍历num1和num2的每一位数字,将它们相乘的结果累加到intRes数组中对应的位置上。这里需要注意的是,由于num1和num2是字符串表示的整数,所以在计算时需要将字符转换为对应的数字值(通过减去字符’0’的ASCII码值)。

     // 使用两层循环遍历num1和num2的每一位数字
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    // 将num1的第i位数字与num2的第j位数字相乘,然后加上intRes数组中对应位置的值
                    intRes[i + j] += (num1.charAt(i) - 48) * (num2.charAt(j) - 48);
                }
            }
    
  5. 对intRes数组进行进位处理。从数组的最后一位开始向前遍历,如果当前位的数字大于等于10,则需要将其除以10加上前一位的值。同时,将当前位的值更新为除以10后的余数

     // 从intRes数组的最后一位开始向前遍历,如果当前位的数字大于等于10,则需要将其除以10并加上前一位的值
            for (int i = intRes.length - 1; i > 0; i--) {
                if (intRes[i] >= 10) {
                    intRes[i - 1] += intRes[i] / 10;
                    intRes[i] %= 10;
                }
            }
    
  6. 最后,将intRes数组中的每个元素转换为字符串,拼接起来得到最终的相乘结果。拼接起来,形成最终的乘积结果。这个结果被赋值给变量res,并作为方法的返回值。

        // 遍历intRes数组,将每个元素转换为字符串并拼接到res中
        for (int i = 0; i < intRes.length; i++) {
            res += String.valueOf(intRes[i]);
        }
        // 返回最终的相乘结果
        return res;
    }

补充说明

1、为什么在代码思路第3的步骤里,创建一个整型数组intRes是长度为 m+n-1 的呢?

int[] intRes = new int[m + n - 1];

​ 在这段代码中,m + n - 1用于初始化一个长度为m + n - 1的整数数组intRes。这个数组用于存储两个字符串num1和num2相乘的结果

​ 具体来说,如果num1的长度为m,num2的长度为n,那么num1和num2相乘的结果的最大位数就是m + n - 1。

​ 因此,我们需要创建一个长度为m + n - 1的数组来存储结果。

2、在代码思路第4的步骤里,在计算时该怎么将字符转换为对应的数字值呢,又是为什么要减去48呢?

  intRes[i + j] += (num1.charAt(i) - 48) * (num2.charAt(j) - 48);

​ 这段代码的目的是将两个字符串表示的数字相乘,并将结果存储在一个整数数组中。

(num1.charAt(i) - 48)/ (num2.charAt(j) - 48):将num1/num2的第i位字符转换为对应的数字值。

  1. 这里减去48是因为字符’0’的ASCII码值为48
  2. 所以通过减去48可以将字符转换为对应的数字值
  3. (例如,字符’2’的ASCII码值为50,减去48后得到数字2)。

参考代码

这段代码是一个用于实现两个字符串表示的整数相乘的算法。

class Solution {
    public String multiply(String num1, String num2) {
        if (num1.equals("0") || num2.equals("0"))
            return "0";
        int m = num1.length();
        int n = num2.length();
        int[] intRes = new int[m + n - 1];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                intRes[i + j] += (num1.charAt(i) - 48) * (num2.charAt(j) - 48);
            }
        }
        for (int i = intRes.length - 1; i > 0; i--) {
            if (intRes[i] >= 10) {
                intRes[i - 1] += intRes[i] / 10;
                intRes[i] %= 10;
            }
        }
        String res = "";
        for (int i = 0; i < intRes.length; i++) {
            res += String.valueOf(intRes[i]);
        }
        return res;
    }
}

子集

题目

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例 1:

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:

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

提示:

1 <= nums.length <= 10
-10 <= nums[i] <= 10
nums 中的所有元素 互不相同

解题思路

  1. 创建一个空的结果列表 res,用于存储所有可能的子集。
  2. 创建一个临时列表 tmp,用于存储当前正在构建的子集。
  3. 将空列表添加到结果列表 res 中。
  4. 如果输入数组 nums 的长度为 0,直接返回结果列表 res。
  5. 调用辅助函数 helper,传入输入数组 nums、起始索引 0、临时列表 tmp 和结果列表 res。
  6. 在辅助函数 helper 中,遍历输入数组 nums 从起始索引 start 开始的所有元素。 a. 将当前元素添加到临时列表 tmp 中。 b. 递归调用辅助函数 helper,传入输入数组 nums、当前元素的下一个索引 i + 1、临时列表 tmp 和结果列表 res。 c. 将当前临时列表 tmp 的副本添加到结果列表 res 中。 d. 移除临时列表 tmp 中的最后一个元素,回溯到上一步。
  7. 返回结果列表 res。

代码思路

  1. 定义一个名为Solution的类,其中包含两个方法:subsetshelper

  2. subsets方法是主方法,它接受一个整数数组nums作为输入,并返回一个包含所有子集的列表。

     public List<List<Integer>> subsets(int[] nums) 
    
  3. subsets方法中,首先创建一个空的结果列表res和一个临时列表tmp,然后将tmp添加到res中。

    List<List<Integer>> res = new ArrayList<List<Integer>>(); // 存储结果的列表
            List<Integer> tmp = new ArrayList<>(); // 临时列表,用于存储当前子集
            res.add(tmp); // 将空子集添加到结果列表中
    
  4. 如果输入数组nums的长度为0,则直接返回结果列表res

     if (nums.length == 0) // 如果输入数组为空,直接返回结果列表
                return res;
    
  5. 调用辅助方法helper,传入输入数组nums、起始索引0、临时列表tmp和结果列表res

       helper(nums, 0, tmp, res); // 调用辅助函数,生成子集
    
  6. helper方法是一个递归方法,用于生成所有可能的子集。它接受四个参数:输入数组nums、当前处理的起始索引start、临时列表tmp和结果列表res

      // 辅助函数,递归生成子集
        public void helper(int[] nums, int start, List<Integer> tmp, List<List<Integer>> res) 
    
  7. helper方法中,使用一个循环从起始索引start开始遍历输入数组nums

     for (int i = start; i < nums.length; i++)
    
  8. 在每次循环中,将当前元素添加到临时列表tmp中,然后递归调用helper方法,传入下一个索引i + 1、更新后的临时列表tmp和结果列表res

       tmp.add(nums[i]); // 将当前元素添加到临时列表中
                helper(nums, i + 1, tmp, res); // 递归调用辅助函数,处理下一个元素
    
  9. 在递归调用返回后,将当前的临时列表tmp复制一份,并将其添加到结果列表res中。

    res.add(new ArrayList<Integer>(tmp)); // 将当前临时列表复制一份,添加到结果列表中
    
  10. 最后,从临时列表tmp中移除最后一个元素,以便在下一次循环中处理下一个元素。

       tmp.remove(tmp.size() - 1); // 移除临时列表中的最后一个元素,回溯到上一步
    
  11. 当循环结束时,所有的子集都已经生成并添加到结果列表res中,最终返回该列表。

参考代码

这段代码是一个求解给定数组的所有子集的算法。它使用了回溯法来生成所有可能的子集,并将它们存储在一个列表中返回。

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        List<Integer> tmp = new ArrayList<>();
        res.add(tmp);
        if (nums.length == 0)
            return res;
        helper(nums, 0, tmp, res);
        return res;
    }
    public void helper(int[] nums, int start, List<Integer> tmp, List<List<Integer>> res) {
        for (int i = start; i < nums.length; i++) {
            tmp.add(nums[i]);
            helper(nums, i + 1, tmp, res);
            res.add(new ArrayList<Integer>(tmp));
            tmp.remove(tmp.size() - 1);
        }
    }
}

删除链表的倒数第 N 个结点

题目

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

进阶:你能尝试使用一趟扫描实现吗?

示例 1:

image-20231112225051811

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

示例 2:

输入:head = [1], n = 1
输出:[]

示例 3:

输入:head = [1,2], n = 1
输出:[1]

提示:

链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz

解题思路

  1. 创建一个虚拟头节点v,并将其指向原链表的头结点head。这样做的目的是方便处理边界情况,例如当需要删除的是头结点时。
  2. 使用一个循环遍历整个链表,将每个节点添加到一个列表index中。这样我们可以方便地访问链表中的任意节点。
  3. 计算要删除的节点的前一个节点和后一个节点在列表中的索引位置。前一个节点的索引为index.size() - n - 1,后一个节点的索引为index.size() - n + 1
  4. 根据计算出的索引位置,更新前一个节点的next指针,使其指向后一个节点或null(如果后一个节点不存在)。
  5. 返回虚拟头节点v的下一个节点,即删除倒数第n个节点后的链表头结点。

代码思路

  1. 创建一个虚拟头节点v,并将其指向原链表头节点head。这样做是为了方便处理边界情况,例如当需要删除的是头节点时。

     // 移除链表中倒数第n个节点的方法
        public ListNode removeNthFromEnd(ListNode head, int n) {
            ListNode v = new ListNode(0, head); // 创建一个虚拟头节点,指向原链表头节点
    
  2. 创建一个名为handle的指针,指向虚拟头节点v。

    ListNode handle = v; // 创建一个指针,指向虚拟头节点
    
  3. 创建一个名为index的列表,用于存储链表中所有节点的引用。

       List<ListNode> index = new ArrayList<>(); // 创建一个列表,用于存储链表中所有节点的引用
    
  4. 使用while循环遍历链表,将每个节点的引用添加到index列表中。

    // 遍历链表,将每个节点的引用添加到列表中
            while (v != null) {
                index.add(v);
                v = v.next;
            }
    
  5. 计算要删除的节点的前一个节点和后一个节点在index列表中的索引位置pre和next。

      // 计算要删除的节点的前一个节点和后一个节点在列表中的索引位置
            int pre = index.size() - n - 1;
            int next = index.size() - n + 1;
    
  6. 根据pre和next的值,更新前一个节点的next指针,使其指向后一个节点或null(如果后一个节点不存在)。

     // 更新前一个节点的next指针,使其指向后一个节点或null(如果后一个节点不存在)
            index.get(pre).next = next >= 0 && next < index.size() ? index.get(next) : null;
    
  7. 返回处理后的链表头节点handle.next。

             // 返回处理后的链表头节点
        return handle.next;

参考代码

这段代码是用于删除链表中倒数第n个节点。

public class ListNode {
    int val;
    ListNode next;
    ListNode() {
    }
    ListNode(int val) {
        this.val = val;
    }
    ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode v = new ListNode(0, head);
        ListNode handle = v;
        List<ListNode> index = new ArrayList<>();
        while (v != null) {
            index.add(v);
            v = v.next;
        }
        int pre = index.size() - n - 1;
        int next = index.size() - n + 1;
        index.get(pre).next = next >= 0 && next < index.size() ? index.get(next) : null;
        return handle.next;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

面向切面:AOP

面向切面&#xff1a;AOP 大家好&#xff0c;今天本篇博客我们来了解Spring里边的另一个重要部分&#xff0c;叫做AOP&#xff0c;也就是我们说的面向切面编程。 1、场景模拟 首先第一部分&#xff0c;咱们做一个场景模拟。我们先写一个简单的例子&#xff0c;然后通过例子引…

探索向量数据库 | 重新定义数据存储与分析

随着大模型带来的应用需求提升&#xff0c;最近以来多家海外知名向量数据库创业企业传出融资喜讯。 随着AI时代的到来&#xff0c;向量数据库市场空间巨大&#xff0c;目前处于从0-1阶段&#xff0c;预测到2030年&#xff0c;全球向量数据库市场规模有望达到500亿美元&#xff…

CSDN每日一题学习训练——Java版(数据流的中位数、乘积最大子数组、旋转链表)

版本说明 当前版本号[20231113]。 版本修改说明20231113初版 目录 文章目录 版本说明目录数据流的中位数题目解题思路代码思路参考代码 乘积最大子数组题目解题思路代码思路参考代码 旋转链表题目解题思路代码思路参考代码 数据流的中位数 题目 中位数是有序列表中间的数。…

DevChat:开发者专属的基于IDE插件化编程协助工具

DevChat&#xff1a;开发者专属的基于IDE插件化编程协助工具 一、DevChat 的介绍1.1 DevChat 简介1.2 DevChat 优势 二、DevChat 在 VSCode 上的使用2.1 安装 DevChat2.2 注册 DevChat2.3 使用 DevChat 三、DevChat 的实战四、总结 一、DevChat 的介绍 在AI浪潮的席卷下&#x…

国际化:i18n

什么是国际化&#xff1f; 国际化也称作i18n&#xff0c;其来源是英文单词 internationalization的首末字符和n&#xff0c;18为中间的字符数。由于软件发行可能面向多个国家&#xff0c;对于不同国家的用户&#xff0c;软件显示不同语言的过程就是国际化。通常来讲&#xff0…

【BMC】jsnbd介绍

jsnbd介绍 本文主要介绍一个名为jsnbd的开源项目&#xff0c;位于GitHub - openbmc/jsnbd&#xff0c;它实现了一个前端&#xff08;包含HTML和JS文件&#xff09;页面&#xff0c;作为存储服务器&#xff0c;可以指定存储内容&#xff1b;还包含一个后端的代理&#xff0c;这…

【chatglm3】(3):在AutoDL上,使用4090显卡,部署ChatGLM3API服务,并微调AdvertiseGen数据集,完成微调并测试成功!附视频演示。

在AutoDL上&#xff0c;使用4090显卡&#xff0c;部署ChatGLM3API服务&#xff0c;并微调AdvertiseGen数据集&#xff0c;完成微调并测试成功&#xff01; 其他chatgpt 和chatglm3 资料&#xff1a; https://blog.csdn.net/freewebsys/category_12270092.html 视频地址&#…

【C++入门篇】保姆级教程篇【下】

目录 一、运算符重载 1&#xff09;比较、赋值运算符重载 2&#xff09; 流插入留提取运算符重载 二、剩下的默认成员函数 1&#xff09;赋值运算符重载 2&#xff09;const成员函数 3&#xff09;取地址及const取地址操作符重载 三、再谈构造函数 1&#xff09;初始化列表 …

SparkSQL之Analyzed LogicalPlan生成过程

经过AstBuilder的处理&#xff0c;得到了Unresolved LogicalPlan。该逻辑算子树中未被解析的有UnresolvedRelation和UnresolvedAttribute两种对象。Analyzer所起到的主要作用就是将这两种节点或表达式解析成有类型的&#xff08;Typed&#xff09;对象。在此过程中&#xff0c;…

链表相关部分OJ题

&#x1f493;作者简介&#x1f44f;&#xff1a;在校大二迷茫大学生 &#x1f496;个人主页&#x1f389;&#xff1a;小李很执着 &#x1f497;系列专栏&#xff1a;Leetcode经典题 每日分享&#xff1a;人总是在离开一个地方后开始原谅它❣️❣️❣️———————————…

“第六十七天”

各位&#xff0c;昨天查找子串的方法想起来了&#xff0c;就是那个KMP算法......自己理解都有点困难&#xff0c;还看看能不能想一下&#xff0c;确实很困难啊。 不要忘了toupper函数和tolower函数不是直接改变字符的大小写&#xff0c;而是返回对应的大小写的值&#xff0c;需…

pytest-bdd快速示例和问题解决

BDD 与 pytest-bdd BDD 即 Behavior-driven development&#xff0c;行为驱动开发。BDD行为驱动是一种敏捷开发模式, 重点在于消除开发/测试对需求了解的歧义及用户场景的验证。 pytest-bdd 是一个BDD测试框架&#xff0c;类似于behave, cucumber。它可以统一单元测试和功能测…

【Git】第四篇:基本操作(理解工作区、暂存区、版本库)

Git 工作区、暂存区和版本库 工作区&#xff1a;就是我们创建的本地仓库所在的目录暂存区&#xff1a; stage或index&#xff0c;一般放在.git(可隐藏文件)目录下的index文件&#xff08;.git/index&#xff09;中&#xff0c;所以我们把暂存区有时候也叫做索引&#xff08;in…

飞书开发学习笔记(五)-Python快速开发网页应用

飞书开发学习笔记(五)-Python快速开发网页应用 一.下载示例代码 首先进入飞书开放平台: https://open.feishu.cn/app 凭证与基础信息 页面&#xff0c;在 应用凭证 中获取 App ID 和 App Secret 值。 教程和示例代码位置:https://open.feishu.cn/document/home/integrating-…

C语言 每日一题 牛客网 11.13 Day17

找零 Z国的货币系统包含面值1元、4元、16元、64元共计4种硬币&#xff0c;以及面值1024元的纸币。 现在小Y使用1024元的纸币购买了一件价值为N(0 < N≤1024)的商品&#xff0c;请问最少他会收到多少硬币&#xff1f; 思路 运用if语句进行判断分类 代码实现 int main() {…

基于php+thinkphp的网上书店购物商城系统

运行环境 开发语言&#xff1a;PHP 数据库:MYSQL数据库 应用服务:apache服务器 使用框架:ThinkPHPvue 开发工具:VScode/Dreamweaver/PhpStorm等均可 项目简介 系统主要分为管理员和用户二部分&#xff0c;管理员主要功能包括&#xff1a;首页、个人中心、用户管理、图书分类…

jupyter lab常用插件集合

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

毕业设计项目:基于java+springboot的共享单车信息网站

运行环境 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Ma…