数据结构与算法 —— 链表linked list(02)

我们继续来看链表的第二道题,来自于leetcode:

两数相加

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

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

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

分析:

  因为是位数按照逆序方式存储,所以链表的前置节点是地位,直接循环链表相加,生成新的链表即可。这里要注意,链表1和链表2长度不一样的情况。

代码:

class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None

def addTwoNumbers(l1, l2):
    """
    :type l1: ListNode
    :type l2: ListNode
    :rtype: ListNode
    """
    pre_node = ListNode(0)
    cur = pre_node
    n = 0
    while l1 or l2:
        n1 = n2 = 0
        if l1:
            n1 = l1.val
            l1 = l1.next
        if l2:
            n2 = l2.val
            l2 = l2.next
        sumnum = n1 + n2 + n
        n = sumnum / 10
        cur.next = ListNode(sumnum % 10)
        cur = cur.next
        if l1:
            l1 = l1.next
        if l2:
            l2 = l2.next
    if n > 0:
        cur.next = ListNode(n)
    return pre_node.next

进阶版的两数相加,来自于leetcode:

两数相加II

给定两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。

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

进阶:

如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。

示例:

输入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出: 7 -> 8 -> 0 -> 7

分析:

  因为数字最高位位于链表的开始,而加减法我们不倾向于从高位做加减,但是又不允许对列表做翻转,那我们想到一个数据结构,栈。栈是先进后出,可以把列表压进一个栈中,再循环出栈的时间先出的就是低位,后出的就是高位,我们再按照上一个demo的方法做加减就好了。代码如下:

class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None

class Stack:
    """模拟栈"""

    def __init__(self):
        self.items = []

    def isEmpty(self):
        return len(self.items) == 0

    def push(self, item):
        self.items.append(item)

    def pop(self):
        return self.items.pop()

    def peek(self):
        if not self.isEmpty():
            return self.items[len(self.items) - 1]

    def size(self):
        return len(self.items)

class Solution(object):
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        s1 = Stack()
        s2 = Stack()
        n = 0
        cur_node = ListNode(-1)
        while l1:
            s1.push(l1.val)
            l1 = l1.next
        while l2:
            s2.push(l2.val)
            l2 = l2.next
        while (not s1.isEmpty()) or (not s2.isEmpty()) or n:
            num1 = s1.pop() if not s1.isEmpty() else 0
            num2 = s2.pop() if not s2.isEmpty() else 0
            sumnum = num1 + num2 + n
            n = sumnum / 10
            cur_node.val = sumnum % 10
            pre_node = ListNode(-1)
            pre_node.next = cur_node
            cur_node = pre_node

        return cur_node.next

  学习技术交流群:226704167,愿和各位一起进步!



原文地址:https://www.cnblogs.com/lip0121/p/8721267.html

时间: 2024-10-11 23:06:34

数据结构与算法 —— 链表linked list(02)的相关文章

数据结构与算法-链表的基本操作---ShinPans

//链表操作:建立.插入.删除.查找.倒置.删除等基本操作 #include<stdio.h> #include<stdlib.h> typedef  struct LNode {       int data;       structLNode *next; }LNode,*Llist; LNode *creat_head();//创建一个空表 void creat_list(LNode *,int);//创建一个长度为n的线性链表 void insert_list(LNode

python数据结构与算法——链表

具体的数据结构可以参考下面的这两篇博客: python 数据结构之单链表的实现: http://www.cnblogs.com/yupeng/p/3413763.html python 数据结构之双向链表的实现: http://www.cnblogs.com/yupeng/p/3413800.html 我这里只实现了单链表的类型,代码也相对精简一点: 先构造关于节点的类: 1 class Node: 2 def __init__(self,data=None,next=None): 3 self

数据结构与算法 - 链表

链表 题型1:数组和链表的区别是什么? 数组和链表的区别主要表现在以下几个方面: 1)逻辑结构.数组必须事先定义固定的长度,不能适应数据动态地增减.当数组中插入.删除数据项时,需要移动其他数据项.而链表采用动态分配内存的形式实现,可以适应数据动态第增减的情况,需要时可以用new/malloc分配内存空间,不需要时使用delete/free将已分配的空间释放,插入和删除元素不需要移动数据项. 2)内存结构.数组从栈中分配空间,链表从堆中分配空间. 3)数组中的数据在内存中是顺序存储的,而链表是随机

数据结构和算法--链表一之单向链表的简单实现

链表在我们java中也是一种基础的数据结构,可以理解成是一种和数组同级的数组结构,正如我们所知,在我们使用这集合ArrayList和LinkedList的时候,总会学习底层数组实现的ArrayList和双向链表实现的LinkedList的区别.在这里,我们将要讲说的是单向链表的简单实现,让我们体会一下链表在实现增删改查的时候是怎么样的一个操作,在和前边涉及到的数组的增删改查进行对比,得到我们学习的结论,数组的增删效率低于链表结构,查改效率高于链表结构! 什么叫做单向链表,我们可以理解为一个一个节

数据结构和算法-链表

链表分类 单向链表 双向链表 优势: 删除某个节点更加高效, 可以快速找到前驱节点 可以方便的在某个节点前插入元素 循环链表 当要处理的数据具有环形结构的时候, 适合循环链表. 如约瑟夫环问题 双向循环链表 数组的缺点是大小固定, 一旦声明长度就要占用连续的内存空间, 当空间不够用时更换更大的空间, 此时就需要将原数组的所有数据迁移过去, 比较费时. 链表则可以动态扩容. 数组在查询上可以更快, 链表在插入和删除上更快, 为了结合数组和链表的优点, 有同时使用的情况, 比如一个网站的用户注册,

数据结构与算法-链表查找倒数第K个值

查找链表中倒数第k个结点题目:输入一个单向链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针.链表结点定义如下: struct ListNode { int m_nKey; ListNode* m_pNext; }; int FindCoundDownInList(pListNode head,int num) { pListNode p1,p2; p1=p2=head; while(num-->0 && p1!=NULL) p1=p1->m_pNext; i

数据结构与算法-链表反转

1.输入一个链表的头结点,从尾到头反过来输出每个结点的值.链表结点定义如下:struct ListNode{      int       m_nKey;      ListNode* m_pNext;};分析:这是一道很有意思的面试题.该题以及它的变体经常出现在各大公司的面试.笔试题中.看到这道题后,第一反应是从头到尾输出比较简单.于是很自然地想到把链表中链接结点的指针反转过来,改变链表的方向.然后就可以从头到尾输出了. 接下来的想法是从头到尾遍历链表,每经过一个结点的时候,把该结点放到一个栈

数据结构与算法-链表就地逆置

链表操作,单链表就地逆置 void Inverse(LinkList &L) { LNode *p, *q; p = L->next; /*记录第一个结点地址*/ L->next = NULL; /*把链表设置成空表*/ while (p != NULL) /*依次按头插法将各结点插入,就实现了逆置*/ { q = p; /*用q记录待插入结点地址*/ p = p->next; /*用p记录待插入结点的后继结点地址*/*/ q->next = L->next; /*将

javascript数据结构与算法--链表

链表与数组的区别?  1. 定义: 数组又叫做顺序表,顺序表是在内存中开辟一段连续的空间来存储数据,数组可以处理一组数据类型相同的数据,但不允许动态定义数组的大小,即在使用数组之前必须确定数组的大小.而在实际应用中,用户使用数组之前有时无法准确确定数组的大小,只能将数组定义成足够大小,这样数组中有些空间可能不被使用,从而造成内存空间的浪费. 链表是一种常见的数据组织形式,它采用动态分配内存的形式实现.链表是靠指针来连接多块不连续的的空间,在逻辑上形成一片连续的空间来存储数据.需要时可以用new分