1、Two Sum / Add Two Numbers

数据结构的意义:

日常工作中遇到的问题可以用算法来有效解决,比如用热土豆问题,推销员问题等。而实现这些算法的有效手段,就是利用不同的数据结构了。比图,热土豆问题可以用队列或者链表,推销员问题用树。

简而言之就是,问题需要用算法来解决,实现这些算法就在于数据结构的掌握了。

1、Two sum

题目:给定一个整数组成的数组,给定一个特定的target,这个target是这个数组中的元素相加得到的。要求返回这两个元素在数组中的索引。
可以假设,在这个数组中只有唯一解,并且不能使用同一个元素。

例子

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1]

作为刚刷的第一题,踩了几个坑:如果数组是[3,3],那么返回的索引list.index(3)是相同的。···· 如果用两个for循环,时间复杂度是O(n2)。超出时间限制。

解题技巧:不能用index,就用字典进行索引,不能用两个for循环,就用加数作为value,被加数作为key。

解:

        dict_nums = {}
        #字典以加数为key
        for n in range(len(nums)):
            m = target-nums[n]
            #如果m已经在字典中了,说明列表中已经有符合条件的加数被存入了字典,这个加数的key就是索引值,得到解
            if m in dict_nums:
                return dict_nums[m],n
            else:
            #如果m不在字典中,以m为key,索引值n为value存入字典中,待用。
                dict_nums[nums[n]]=n

2. Add Two Numbers

题目:给定两个非空链表,代表两个正数,数字以逆序存储在链表中,链表中每个节点存储一个单独的数字。要求将这两个数字相加,以同样的形式(逆序)返回链表。
可以假设,除了0本身,数字不以0开头。

例子:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.

需要注意的坑:

  • 1、两个数字长度不一样
  • 2、有列表为空
  • 3、两个数字都为0
    用到的技巧:
  • 1、取余数:若n比10小,那么n%10=n
  • 2、取整数:若n比10小,那么n//10=0
    -------------------------------------------------------------------------------------------
    可以利用上面两个方法,可以求得组成一个数字(807)的每个元素(8/0/7)。
    余数 = x % 10
    x = x//10
    807//10=80,下次余数是0,在下次是8。
    -------------------------------------------------------------------------------------------
    我的做法:
  • 1、依次读取链表,利用while将个位数乘10,百位数再乘10,将链表中的数字表示出来。
  • 2、将上面表示的两个链表相加,得到和以后,再按照上面技巧求得组成这个数字的每个元素,得到列表。
  • 3、因为要求链表逆序存储,所以将上一步得到的列表反转以后,再按照链表添加节点的方法,依次添加个元素,得到链表。

我的缺点:

  • 1、因为考虑到不能踩“两个数字不等”的坑,于是连续用了几个while。。。,其实用一个or就可以将两个数字联系起来了,一个为空时,另一个为真就可以让while继续循环下去。
  • 2、因为考虑不能踩“单个数字相加可能有进位”的坑,于是把两个数字单独表示出来以后再相加再返回链表。。。其实可以再加一个变量carry表示进位符。这样,可以将单个的数字相加, 想办法计算下一个位的时候,加上carry就行了。

为了解题方便,可以多加变量

链表从head添加节点的步骤(已经有了head了)
1、构造一个新的节点
cur_new = ListNode(carry%10)
2、新来的节点的next指向原链表的head
cur_new.next = cur
3、head没了,就将新来的节点设置为head
cur_head = cur_new

比较好的改进:

def addTwoNumbers(self, l1, l2):
    dummy = cur = ListNode(0)#定义一个头
    carry = 0
    while l1 or l2 or carry:#
        if l1:
            carry += l1.val
            l1 = l1.next
        if l2:
            carry += l2.val
            l2 = l2.next
        cur.next = ListNode(carry%10)
        cur = cur.next
        carry //= 10
    return dummy.next

但是这个链表,不是从头添加节点,是每次从链表末端添加节点,时间复杂度可能比较高。
0
0->7
0->7->0
0->7->0->8

你可能感兴趣的:(1、Two Sum / Add Two Numbers)