我们都知道算法是程序员成长重要的一环,怎么才能提高算法呢, 出来在网上看视频之外,动手练习是非常重要的。leetcode 就是一个非常好的锻炼平台。
1. 两数之和,在 leetcode 里面是属于 easy 级别的。我们看看他的题目和解法。
题目: 给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
例子:
给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] 题目说的很清楚, 给出一个列表和一个 目标值,找出列表中两数之和是 目标值的, 一个数不可重复使用。
思路:
我的思路是 循环遍历每一个数记作 index,然后 用 目标值(target)减去 index,看结果在不在这个列表里。
代码:
1 def twoSum(self, nums, target): 2 """ 3 :type nums: List[int] 4 :type target: int 5 :rtype: List[int] 6 """ 7 res_list = [] 8 for index, item in enumerate(nums): 9 res = target - item 10 if res in nums: 11 res_index = nums.index(res) 12 if res_index != index: 13 res_list.append(index) 14 res_list.append(res_index) 15 break 16 17 return res_list
总结:我的这个解法虽然不是最优解,但是总比双重 for 循环好一点(自我感觉)。时间复杂度 为 O(n), 空间复杂度 为 O(n)。
2. 两数相加
题目: 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
例子:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807
思路:逆序的两个简单链表,取出数相加 大于10 进1,别忘了最后一位相加大于 10 所进的 1.
代码:
# 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 """ res = ListNode(0) cur = res carry = 0 while l1 or l2: n1 = l1.val if l1 != None else 0 n2 = l2.val if l2 != None else 0 sum = n1 + n2 + carry carry = 1 if sum >= 10 else 0 cur.next = ListNode(sum % 10) cur = cur.next l1 = l1.next if l1 != None else None l2 = l2.next if l2 != None else None if carry != 0: cur.next = ListNode(1) return res.next
总结: 这是我模仿 Java 的写法,自己还没有想出特别的解法,有优秀的 Python 解法,大佬一定评论,让我学习学习。时间复杂度 O(n), leetcode 官方解释的更准确是:
时间复杂度:O(max(m, n))O(max(m,n)),假设 mm 和 nn 分别表示 l1l1 和 l2l2 的长度,上面的算法最多重复 max(m, n)max(m,n) 次。
空间复杂度:O(max(m, n))O(max(m,n)), 新列表的长度最多为 max(m,n) + 1max(m,n)+1。
参考一下。
ps:
如果有不合理或者错误的地方,一定评论我,或者私聊我改正,以防误人子弟。不胜感激。谢谢。同时也期盼与每一位的相遇相识。