LeetCode第一天
一天一步慢慢做吧,准备先用python写一遍,然后再用java巩固一下,python底子不太好,慢慢来。
1.Two Sum
采用两层for循环去遍历list的值时,超时了,使用java的话,可以使用冒泡法,在内层循环可以把变量设为j=i+1,这样可以从O(n2)降低到O(n),比较好使。但是python不太熟悉,看了解析才了解是怎么完成的这个操作。
class Solution: def twoSum(self, nums, target): """ :type nums: List[int] :type target: int :rtype: List[int] """ buff_dict = {} for i, n in enumerate(nums): # 这个枚举类型主要是返回index和value,方便定位 m = target - n # target是给定目标值,m是需要的另一个加数,(存在这个m的话,返回它的index) if m in buff_dict: # 当加数存放在缓冲里,我们返回两个index(此时,缓冲里面的index对应原list里面的value,反正是一一对应的) return [buff_dict[m],i] else: buff_dict[n] = i # 当没有所需要的m时,把这个n记下来,n作为键,把i作为值
2. Add Two Numbers
题目为了降低难度,特意将低位调转到前面,一开始的想法是把这两个链表的数都算出来,然后相加,再去根据每位的数构造链表,涉及到遍历两个表,并且再重新构造表,也是超时了,当初想的好处是不需要考虑到进位,使用数学方法避免进位问题。没有考虑这个的时间复杂度,后期加上。
改为遍历同时更新后,首先判断是否有表为空(其实直接if l1就可以了),用flag标记了进位问题,判断是否需要加一,在加之前考虑了next是否为空,但其实一个if l1就能解决,这也是看了一个分享才知道的。
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def addTwoNumbers(self, l1, l2): """ :type l1: ListNode :type l2: ListNode :rtype: ListNode """ if l1.val == 0 and l1.next == None: return l2 elif l2.val == 0 and l2.next == None: return l1 else: if(l1.val + l2.val > 9 and l1.next == None and l2.next == None): flag = 1 node = ListNode(l1.val + l2.val - 10) node.next = ListNode(1) else: flag = 0 node = ListNode(l1.val + l2.val) final = node while(l1.next != None and l2.next != None): l1 = l1.next l2 = l2.next if(flag == 0): if(l1.val + l2.val > 9): flag = 1 node.next = ListNode(l1.val + l2.val - 10) else: flag = 0 node.next = ListNode(l1.val + l2.val) else: if(l1.val + l2.val > 9): flag = 1 node.next = ListNode(l1.val + l2.val - 10 + 1) else: flag = 0 node.next = ListNode(l1.val + l2.val + 1) node = node.next if(l1.next == None): while(l2.next != None): if(flag == 0): flag = 0 node.next = ListNode(l2.val) else: flag = 0 node.next = ListNode(l2.val + 1) l2 = l2.next node = node.next if(l2.next == None): while(l1.next != None): if(flag == 0): flag = 0 node.next = ListNode(l1.val) else: flag = 0 node.next = ListNode(l1.val + 1) l1 = l1.next node = node.next return final
别人写的代码很简洁,carry相当于flag,之前写的时候发现一个问题,就是头结点的问题,必须先声明一个头结点,但是还不知道值,就只能生成res = ListNode(0)了。返回res.next就好了。
# Definition for singly-linked list. # class ListNode: # # def __init__(self, x): # self.val = x # self.next = None class Solution: def addTwoNumbers(self, l1, l2): """ :type l1: ListNode :type l2: ListNode :rtype: ListNode """ carry = 0; res = n = ListNode(0); while l1 or l2 or carry: # 当l1或l2或有进位时,都执行,就这直接减少了我上面的那种对l1.next是否为空的判断了,ps:如果l1、l2都为空,而有进位时,carry位发生作用 if l1: # 如果l1还有值 carry += l1.val # carry一开始是0,加上l1对应位的值 l1 = l1.next; # 更新l1,后移 if l2: # 如果l2还有值 carry += l2.val; # carry+l1.val再加l2对应位的值 l2 = l2.next; carry, val = divmod(carry, 10) # 这个函数是取商和余数,如果当前的和≥10,carry会等于1,接入到下一次循环 n.next = n = ListNode(val); # 生成下一个结点,值为余数,再更新n,此处n相当于指针,res相当于头结点 return res.next;
不得不说,别人代码写的就是好QAQ,还好没用Lintcode,没有discussion。