python输入两个数求和笔试题_【leetcode】刷题(python & java)解析:【两数相加】 重点【链表】...

给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。

你可以假设除了数字 0 之外,这两个数字都不会以零开头。

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

示例输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)

输出:7 -> 0 -> 8

原因:342 + 465 = 807

在做这道题之前,我们需要简单地了解一下什么是链表。在链表中,每个数据项都被包含在“链结点(Link)”。一个链结点是每个类的对象,这个类可以叫做Link。每个Link对象中都包含一个对下一个链结点引用的字段(通常叫做next)。但是,链表本身的对象中有一个字段指向第一个链结点的引用。以下是链表与结点之间的关系。

5430

这里使用Java为例,创建一个Link类,它包含了一些数据(实际项目也是比这多的)和下一个链结点的引用:class Link{

//数据的定义

public int iData;

public double dDate;

//相关下一个链表

public Link next;

}

解决方案

思路

有了以上的基础了,我们可使用结点数据变量进行跟踪进位,并从包含最低有效位的表头开始模拟逐相加的过程。

在这里插入图片描述

以上是对两数相加方法的可视化:342+465=807,每个结点都包含一个数字,并且是使用逆序存储的。

算法

就像你在纸上计算两个数字的和那样,我们首先从最低有效位也就是列表 l1 和 l2的表头开始相加。由于每位数字都应当处于0…9 的范围内,我们计算两个数字的和时可能会出现“溢出”。例如,5 + 7 = 12。在这种情况下,我们会将当前位的数值设置为 2,并将进位 carry = 1带入下一次迭代。进位 carry必定是 0 或 1,这是因为两个数字相加(考虑到进位)可能出现的最大和为 9 + 9 + 1 = 19。

伪代码如下:将当前结点初始化为返回列表的哑结点。

将进位 carrycarry 初始化为 00。

将 pp 和 qq 分别初始化为列表 l1l1 和 l2l2 的头部。

遍历列表l1和l2直至它们的尾端。将 x设为结点 p 的值。如果 p 已经到达 l1 的末尾,则将其值设置为 0。

将 y设为结点 q 的值。如果 q 已经到达 l2 的末尾,则将其值设置为 0。

设定 sum = x + y + carry。

更新进位的值,carry = sum / 10。

创建一个数值为 (sum mod 10) 的新结点,并将其设置为当前结点的下一个结点,然后将当前结点前进到下一个结点。

同时,将 p 和 q 前进到下一个结点。

检查 carry = 1是否成立,如果成立,则向返回列表追加一个含有数字 1 的新结点。

返回哑结点的下一个结点。

请注意,我们使用哑结点来简化代码。如果没有哑结点,则必须编写额外的条件语句来初始化表头的值。

请特别注意以下情况:

在写代码之前知道数据类型中基本类型以及引用类型之间的区别,本题也需要注意引用类型的使用。

Java代码//创建一个链表的类

class ListNode {

//结点的值

int val;

//指向下一个结点

ListNode next;

//通过参数添加值

ListNode(int x){

val=x;

}

}

public class Demotest {

public static void main(String[] args) {

//定义两个结点,并添加信息

ListNode l1=new ListNode(2);

l1.next=new ListNode(4);

l1.next.next=new ListNode(3);

ListNode l2=new ListNode(5);

l2.next=new ListNode(6);

l2.next.next=new ListNode(4);

ListNode result_listnode = new Demotest().addTwoNumbers(l1,l2);

//打印计算的结果

while(result_listnode!=null) {

System.out.println(result_listnode.val);

result_listnode=result_listnode.next;

}

}

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {

//创建一个计算结果的链表

ListNode dummyHead = new ListNode(0);

ListNode p = l1, q = l2, curr = dummyHead;

//定义一个用于进位的值

int carry = 0;

//通过循环开始计算

while (p != null || q != null) {

int x = (p != null) ? p.val : 0;

int y = (q != null) ? q.val : 0;

int sum = carry + x + y;

carry = sum / 10;

curr.next = new ListNode(sum % 10);

curr = curr.next;

//链表更新

if (p != null) p = p.next;

if (q != null) q = q.next;

}

//验证循环结束后是否还有进位值

if (carry > 0) {

curr.next = new ListNode(carry);

}

//返回去掉创建含有0的链表

return dummyHead.next;

}

}

需要说明的是:原题只要我们写出计算的函数,不需要写出计算的主函数,这里为了自己学习,写出全部程序。

程序运行结果:

5430

Python代码#Definition for singly-linked list.

class ListNode(object):

def __init__(self, x):

self.val = x

self.next = None

#创建一个对象

class Solution:

def addTwoNumbers(self,l1,l2):

#定义一个ListNode

dummyHead=ListNode(0)

p=l1

q=l2

curr=dummyHead

carry=0

while p!=None or q!=None:

x=p.val if p!=None else 0

y=q.val if q!=None else 0

Sum=carry+x+y

carry=int(Sum/10)

curr.next = ListNode(Sum%10)

curr=curr.next

if p!=None:p=p.next

if q!=None:q=q.next

if carry>0:curr.next=ListNode(carry)

return dummyHead.next

#创建l1

l1=ListNode(2)

temp=l1

l1.next=ListNode(4)

l1.next.next=ListNode(3)

#创建l2

l2=ListNode(5)

l2.next=ListNode(6)

l2.next.next=ListNode(4)

#开始运算

result=Solution().addTwoNumbers(l1, l2)

#打印测试

while result!=None:

print(result.val)

result=result.next

5430

复杂度分析时间复杂度:O(max(m,n),假设 m 和 n分别表示 l1 和 l2 的长度,上面的算法最多重复 max(m,n) 次。

空间复杂度:O(max(m,n)), 新列表的长度最多为 max(m,n)+1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值