两数之和,两数相加

中级软考(软件攻城狮)第3章知识点——数据结构与数据运算(线性结构+非线性结构) 本文系统梳理了数据结构中的线性与非线性结构。线性部分详细介绍了线性表(顺序/链式存储及时间复杂度对比)、栈(后进先出特性及应用)、队列(循环队列与双端队列)以及串(空串与子串概念)。非线性部分涵盖数组、矩阵、广义表,重点解析了树结构(二叉树性质、存储方式及遍历方法),并深入讲解了最优二叉树(哈夫曼树)的构建原理与编码应用。全文通过图示对比和实例说明,清晰呈现了各类数据结构的特点、存储方式及典型应用场景。 阅读详情

1,两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。

自主独立写法,只考虑回答正确

思路:两个for循环遍历把所有的两数之和来与targer比较,没有考虑性能优化,只负责回答正确

public int[] twoSum(int[] nums, int target) {
    for (int i = 0; i < nums.length; i++) {
        for (int j = i+1; j < nums.length; j++) {
            if(target == (nums[i] +nums[j])){
                return new int[]{i,j} ;
            }
        }
    }
    return  null ;
}

执行用时:54 ms, 在所有 Java 提交中击败了**27.36%的用户
内存消耗:41.9 MB, 在所有 Java 提交中击败了
16.24%**的用户
通过测试用例:57 / 57

时间复杂度:O(n^2)

考虑时间复杂度,用到Map

思路:用map中的键值对来进行存储,只用遍历一次

public int[] twoSum(int[] nums, int target) {
        int[] ints = new int[2];
        if (nums == null || nums.length==0){
            return ints ;
        }
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int temp = target - nums[i] ;
            //到map中匹配另一半,匹配成功则找到了两数
            if (map.containsKey(temp)){
                ints[0] = i ;
                ints[i] = map.get(temp) ;
            }
            //将数值的值和下标都存储到map中
            map.put(nums[i] , i) ;
        }
        return ints ;
    }

执行用时:5 ms, 在所有 Java 提交中击败了**48.60%的用户
内存消耗:42.6 MB, 在所有 Java 提交中击败了
5.03%**的用户
通过测试用例:57 / 57

时间复杂度:O(n)

继续优化采用双指针思想

思路:在用while循环对数值从头尾两边进入map

    public int[] twoSum(int[] nums, int target) {
        int star = 0 , end = nums.length -1 ;
        HashMap<Integer, Integer> map = new HashMap<>();
        while (star < end){
            if (map.containsKey(target - nums[star])){
                return  new int[]{star , map.get(target -nums[star])} ;
            }else {
                map.put(nums[star] , star) ;
            }
            if (map.containsKey(target - nums[end])){
                return  new int[]{end , map.get(target -nums[end])} ;
            }else {
                map.put(nums[end] , end) ;
            }
            star++ ;
            end-- ;
        }
        return null ;
    }

执行用时:0 ms, 在所有 Java 提交中击败了**100.00%的用户
内存消耗:41.7 MB, 在所有 Java 提交中击败了
34.61%**的用户
通过测试用例:57 / 57

优点:提升了速度

一些问题
  • 为什么要用map,不用set等其他集合

2,两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

常规方法:迭代方法

实现思路:

我们可以遍历两个链表,并且同时从头开始对每个节点进行加法运算。由于链表是按照逆序存储的,因此我们可以从链表头开始遍历,将每个节点的值相加,然后构造一个新的链表来存储结果。如果两个链表的长度不相等,我们可以认为长度短的链表的缺失位为0

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            //创建一个零节点
            ListNode listNode = new ListNode(0);
            ListNode p = l1 ,q = l2 ,curr = listNode ;
            //进位数,用来记录进位
            int carry = 0 ;
            //循环两个链表直到两个都为空为止
            while (p!=null || q!=null){
                //将俩个链表的数相加
                int a = (p !=null)? p.val : 0 ;
                int b = (q != null) ? q.val :0 ;
                int sum  = a + b + carry ;
                //保存进位
                carry = sum / 10 ;
                //创建新节点用来存储相加后的数,并接在curr节点后面
                curr.next = new ListNode(sum % 10);
                curr = curr.next ;
                //在将初始的l1,l2移到下一个节点
                if (p != null) p = p.next ;
                if (q !=null) q = q.next ;
            }
            //最后carry进位,在往后接一个节点
            if (carry>0){
                curr.next = new ListNode(carry) ;
            }
            return listNode.next ;
        }

算法时间复杂度:O(max(m,n)),取决于两个链表的最大长度

方法二:递归方法
public  ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        return addNewTwoNumbers(l1 ,l2 ,0) ;
    }


    private ListNode addNewTwoNumbers(ListNode l1, ListNode l2 , int carry){
        //设置递归结束条件
        if (l1==null && l2==null && carry==0)
            return null ;

         int sum =  (l1 !=null ? l1.val :0) + (l2 !=null ? l2.val :0) + carry;
         carry = sum / 10 ;
         ListNode node = new ListNode(sum % 10);
        node.next = addNewTwoNumbers(l1!=null ? l1.next:null , l2!=null ? l2.next:null ,carry) ;
        return node;
    }
一些问题
  • 迭代和递归的区别(chatgpt)
    迭代是指通过**循环结构**来反复执行一段代码,以达到某种目的。迭代的优点是能够明确控制循环次数,能够在循环过程中方便地修改循环变量的值,并且能够在循环结束后直接返回结果。缺点是代码结构可能比较繁琐,容易出现深度嵌套,不易读写和维护。

递归是指通过**函数的调用**来反复执行一段代码,以达到某种目的。递归的优点是能够简化算法的实现,使代码更加清晰易读,并且能够处理一些复杂的问题,如树的遍历、图的搜索等。缺点是递归需要消耗大量的系统资源,容易导致堆栈溢出等问题,并且可能会出现死循环等错误。

算法】【leetcode】两数之和,两数相加 /* 两数相加 1.链表相当于从个位往上数,计算每一位的和,记录进位,创建节点。 2.使用队列,计算好各位的值,统一创建节点(跟第一个其实差不多) */ function ListNode(val, next) { this.val = val === undefined ? 0 : val; this.next = next === undefined ? null : next; } var addTwoNumbers_2 = function (l1, l2) 阅读详情

相关推荐

力扣LeetCode刷题C++ 两数之和 两数相加

这段代码的核心是 “逐步构建链表”:从无到有创建头节点,之后每计算出一位结果,就往链表末尾加一个新节点,同时让指针p始终保持在末尾,为下一次追加做准备。这样就能把所有计算结果串联成一个完整的链表。

weixin_73793168的博客 1071

数据结构算法两数之和返回两数下标、数组形式整数相加

本文对两道经典例题进行了剖析和实现,通过这两道例题的学习,我们会对C语言解决实际问题进行锻炼。

熬夜秃顶中...... 2033

力扣 (LeetCode)-两数之和,有效的括号,两数相加

Github来源:力扣 (LeetCode)|刷题打卡 | 求星星 ✨ | 给个❤️关注,❤️点赞,❤️鼓励一下作者[已开启]任务一:刷题打卡 * 10 篇大家好,我是魔王哪吒,很高兴认识...

程序员哆啦A梦,蓝胖子 2209

Leetcode c++ 三数之和/ 两数之和/ 两数相加

题1:三数之和 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。 代码: class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { ...

kelseyscat的博客 572

手撕代码之n数之和两数之和、三数之和、最接近的三数之和、四数之和、四数相加 II、两数相加两数相加 II

力扣001. 两数之和 class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { std::unordered_map <int,int> map; for(int i = 0; i < nums.size(); i++) { auto iter = map.find(target - nums[i]

weixin_39770712的博客 352

LeetCode算法题解---两数之和两数相加

目录 一:两数之和 解题思路 代码 二:两数相加 解题思路 代码 一:两数之和 1. 两数之和 难度简单 给定一个整数数组nums和一个目标值target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。 示例: 给定 nums = [2, 7, 11, 15], target = 9 ...

业精于勤荒于嬉 1005

[力扣算法刷题学习]1.两数之和 2.两数相加

力扣算法刷题记录

sls1223074612的博客 310

力扣.两数之和/四数相加||

给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。示例1输入输出[0,1]解释因为nums[0]+nums[1]==9,返回[0,1]。示例2输入输出[1,2]示例3输入输出[0,1]......

wangzai32100的博客 206

Golang每日一练(leetDay0001) 两数之和两数相加、无重复最长子串

1. 两数之和 Two Sum  2.两数相加 Add Two Numbers  3.无重复字符的最长子串 Longest substring without repeating characters

汉阳Hann's Home 6938

快速学会数据结构中的链式队列与循环队列

一种允许从一端插入数据,另外一端删除数据的线性存储结构称为队列。把数据插入的这端称为队列的队尾, 数据删除这端称为队列的队头。插入操作称为入队;删除操作称为出队。先进先出、后进后出数据缓存。

2401_82745609的博客 532

GXF 3.2.0 to 4.0 CUDA 12 路径 API 与数据结构增量分析

分析范围:以仓库中与分支对比为基础,聚焦)可用的公共 API 与数据结构变化。由于 GXF 核心头文件在各 CUDA 版本间共享,下列新增/修改的接口在 CUDA 12 构建上同样生效。对比链接:https://github.com/NVIDIA-ISAAC-ROS/isaac_ros_nitros/compare/release-3.2…release-4.0。

eloudy的专栏 241

数据结构 --- 二叉树&哈希表

本篇数据结构学习笔记分为二叉树、哈希表两大板块。二叉树部分讲解树形基础概念、链式存储方式、前 / 中 / 后序遍历算法,介绍带占位符字符串递归创建二叉树的方法,配套结点计数、深度计算、内存销毁等递归代码实现,补充二叉树核心数学性质。哈希表板块梳理哈希函数、哈希冲突概念,对比开放定址法、链地址法两种冲突解决方案,分析操作的时间复杂度。最后完整给出拉链哈希表五大功能模块的 C 语言实现代码,讲解插入、查找、打印、销毁的执行流程,同时点明现有代码的缺陷与优化方向。

2401_86288082的博客 691

数据结构:双向链表 内核链表 链式队列

本文介绍了链表操作中的几种常用算法技巧。主要包括:1. 快慢指针法(查找中间节点和倒数第k个节点);2. 链表基本操作(查找、删除特定节点、逆序、排序);3. 环形链表处理(判断是否有环、获取环入口);4. 双向链表操作(头插尾插、头删尾删);5. 内核链表与普通链表的区别;6. 队列的基本概念(FIFO特性)及其应用。这些算法涵盖了链表操作的核心技术,包括单/双向链表处理、环形链表检测以及队列实现等常见数据结构问题。

yxg0505的博客 438

数据结构】C语言实现链式二叉树

本文系统介绍了链式二叉树的实现与操作,包括节点创建、遍历算法(先序、中序、后序、层序)、节点统计(总数、叶子节点、左右子节点)、高度计算、层级节点查询、节点查找、完全二叉树判断、二叉树翻转和销毁等16个核心功能。重点阐述了递归思想在二叉树操作中的应用,并展示了队列在层序遍历和完全二叉树判断中的关键作用。所有操作均通过C语言实现,提供了完整的代码示例,为理解和实现链式二叉树数据结构提供了全面参考。

Jupiter1007的博客 323

数据结构】平衡二叉树(AVL)与哈夫曼树

本文系统讲解了AVL树和哈夫曼树两大高频考点。AVL树通过平衡因子(-1/0/1)实现自平衡,详细解析了LL、RR、LR、RL四种旋转操作及其应用场景,确保查找效率维持在O(log n)。哈夫曼树部分阐述了其构造方法(每次合并最小权值节点)和WPL计算,并给出哈夫曼编码的生成规则。文章配备典型例题和记忆口诀,强调AVL旋转与哈夫曼WPL计算是重点题型,建议重点掌握平衡因子判断与旋转操作,以及哈夫曼树的构建流程。

bianyuan172的博客 270

408 数据结构|完全二叉树两道典型题:第 6 层叶结点数与叶结点总数

除最后一层外:全部满最后一层:允许不满,但必须从左到右连续排列○/ \○ ○/ \ / \○ ○ ○ ○/ \ /○ ○ ○尽量让这一层直接成为最后一层= 39总结点数 = 2n0 - 1或总结点数 = 2n0最少 = 2n0 - 1最多 = 2n0n0 = 124最少 = 2×124 - 1 = 247最多 = 2×124 = 248。

2301_82049134的博客 154

数据结构——双向链表(附图文讲解 | 超详细)

这篇博客将从全面讲解数据结构中的双向链表链表(带头双向循环链表)双向链表主要表现就是拥有头节点,链表永不为空,不需要二级指针;可以通过一个节点找到上一个或者下一个节点;头尾相连呈环状。它主要结构是由,这三个结构组成,通过prev找到前一个结点,next找下一个结点,data储存链表数据如图所示。

king_linlin的博客 323

Java 数据结构详解:从栈、队列、链表到红黑树、B-Tree 与位图

本文摘要:数据结构解决的是如何高效组织数据以优化常见操作的问题。文章以Java为例,讲解了8种核心数据结构(栈、队列、链表、散列表、二叉搜索树、红黑树、B树、位图)的实现与应用。重点分析了复杂度概念(O(1)到O(n²))和数据结构选择标准(查询/插入效率、有序性等)。通过括号匹配和BFS等典型示例,展示了栈和队列的实际应用场景。文中推荐优先使用ArrayDeque实现栈/队列,并对比了不同数据结构的适用场景和Java标准库实现(如HashMap、TreeMap等)。全文基于Java 8+,强调理解数据结构

qq_29029209的博客 825
上一篇: 原码反码补码
T-timo
博客等级 码龄8年 2粉丝 · 9原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值