Python学习(Leetcode 算法题解【21~40】)

来源:互联网 发布:淘宝客服的上班时间 编辑:程序博客网 时间:2024/06/06 05:22

343. Integer Break

题目:
Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.

For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4).

Note: You may assume that n is not less than 2 and not larger than 58.
思路:
对于每个大于5的数而言,分解为2×3总是大于其他的。最大的值就是将其分解为2和3的乘积。
代码:

class Solution(object):    def integerBreak(self, n):        """        :type n: int        :rtype: int        """        if n==1:            return None        if n==2:            return 1        if n==3:            return 2        if n==4:            return 4        if n==5:            return 6        if n==6:            return 9        return 3*self.integerBreak(n-3)

217. Contains Duplicate

题目:
Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.
思路:比较数组长度和特有值长度即可。
代码:

class Solution(object):    def containsDuplicate(self, nums):        """        :type nums: List[int]        :rtype: bool        """        uniquenums=list(set(nums))        return len(uniquenums)!=len(nums)

350. Intersection of Two Arrays II

题目:
Given two arrays, write a function to compute their intersection.

Example:
Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2].

Note:
Each element in the result should appear as many times as it shows in both arrays.
The result can be in any order.
Follow up:
What if the given array is already sorted? How would you optimize your algorithm?
What if nums1’s size is small compared to nums2’s size? Which algorithm is better?
What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once?
思路:一般思路即统计各个元素在两个列表中出现的次数,取其较小的值,加入到返回列表中。
对于后面几个问题,暂时没有进行考虑。
代码:

class Solution(object):    def intersect(self, nums1, nums2):        """        :type nums1: List[int]        :type nums2: List[int]        :rtype: List[int]        """        ret=[]        uniquenums1=list(set(nums1))        for num in uniquenums1:            ret+=min(nums2.count(num),nums1.count(num))*[num]        return ret

268. Missing Number

题目:

Given an array containing n distinct numbers taken from 0, 1, 2, …, n, find the one that is missing from the array.

For example,
Given nums = [0, 1, 3] return 2.

Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
思路:太简单。
代码:

class Solution(object):    def missingNumber(self, nums):        """        :type nums: List[int]        :rtype: int        """        return len(nums)*(len(nums)+1)/2-sum(nums)

319. Bulb Switcher

题目:
There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off every second bulb. On the third round, you toggle every third bulb (turning on if it’s off or turning off if it’s on). For the ith round, you toggle every i bulb. For the nth round, you only toggle the last bulb. Find how many bulbs are on after n rounds.

Example:

Given n = 3.

At first, the three bulbs are [off, off, off].
After first round, the three bulbs are [on, on, on].
After second round, the three bulbs are [on, off, on].
After third round, the three bulbs are [on, off, off].

So you should return 1, because there is only one bulb is on.
思路:
对每个位置的灯泡而言,如果不是平方数,那么它被开关的次数就是偶数次(它的每个约数都会使它被开关一次),最终就是关闭的。因此只要知道比n小的平方数有多少个即可。等价于求n的开方。
代码:

class Solution(object):    def bulbSwitch(self, n):        """        :type n: int        :rtype: int        """        return int(n**0.5)

这道题是典型的思路比代码重要,最终分析清楚之后,只要一句代码就可以解决问题了。

144. Binary Tree Preorder Traversal

题目:
Given a binary tree, return the preorder traversal of its nodes’ values.

For example:
Given binary tree {1,#,2,3},
1
\
2
/
3
return [1,2,3].

Note: Recursive solution is trivial, could you do it iteratively?
思路:递归
代码:

# Definition for a binary tree node.# class TreeNode(object):#     def __init__(self, x):#         self.val = x#         self.left = None#         self.right = Noneclass Solution(object):    def preorderTraversal(self, root):        """        :type root: TreeNode        :rtype: List[int]        """        if root is None:            return []        ret=[root.val]        ret=ret+self.preorderTraversal(root.left)+self.preorderTraversal(root.right)        return ret

94. Binary Tree Inorder Traversal##

题目:
Given a binary tree, return the inorder traversal of its nodes’ values.

For example:
Given binary tree [1,null,2,3],
1
\
2
/
3
return [1,3,2].
思路:递归。
代码:

# Definition for a binary tree node.# class TreeNode(object):#     def __init__(self, x):#         self.val = x#         self.left = None#         self.right = Noneclass Solution(object):    def inorderTraversal(self, root):        """        :type root: TreeNode        :rtype: List[int]        """        ret=[]        if root is None:            return []        else:            ret+=self.inorderTraversal(root.left)            ret+=[root.val]            ret+=self.inorderTraversal(root.right)        return ret            

206. Reverse Linked List

题目:
Reverse a singly linked list.
思路:通过循环实现。
代码:

# Definition for singly-linked list.# class ListNode(object):#     def __init__(self, x):#         self.val = x#         self.next = Noneclass Solution(object):    def reverseList(self, head):        """        :type head: ListNode        :rtype: ListNode        """        if head is None:            return None        if head.next is None:            return head        headahead=None        while (head.next is not None):            headnext=head.next            head.next=headahead            headahead=head            head=headnext        headret=ListNode(head.val)        headret.next=headahead        return headret

13. Roman to Integer

题目:
Given a roman numeral, convert it to an integer.

Input is guaranteed to be within the range from 1 to 3999.

思路:罗马数字是累加制,唯一需要注意的地方是一旦前面的数字小于后面的数字,则代表数字相减。
代码:

class Solution(object):    def romanToInt(self, s):        """        :type s: str        :rtype: int        """        D={'I':1,'X':10,'C':100,'M':1000,'V':5,'L':50,'D':500}        num=0        i=0        while(i<len(s)-1):            if D[s[i]]<D[s[i+1]]:                num=num+D[s[i+1]]-D[s[i]]                i=i+2            else:                num=num+D[s[i]]                i=i+1        if i==len(s)-1:            return num+D[s[i]]        else:            return num

318. Maximum Product of Word Lengths

题目:
Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0.

Example 1:
Given [“abcw”, “baz”, “foo”, “bar”, “xtfn”, “abcdef”]
Return 16
The two words can be “abcw”, “xtfn”.

Example 2:
Given [“a”, “ab”, “abc”, “d”, “cd”, “bcd”, “abcd”]
Return 4
The two words can be “ab”, “cd”.

Example 3:
Given [“a”, “aa”, “aaa”, “aaaa”]
Return 0
No such pair of words.
思路:
构造函数,用来判断两个数是否包含相同字符的。并在主函数中对字符串进行两两比较。但是实际采用String.count的方式来判断两个字符串是否相等,运行时间比较久。通过构造二进制数的方式来实现这类比较问题,运行速度会得到大大提高。
代码:

class Solution(object):    def maxProduct(self, words):        """        :type words: List[str]        :rtype: int        """        nums = []        size = len(words)        for w in words:            nums+=sum(1 << (ord(x) - ord('a')) for x in set(w))        ans = 0        for x in range(size-1):            for y in range(x,size):                if not (nums[x] & nums[y]):                    ans = max(len(words[x]) * len(words[y]), ans)        return ans

这种解法中需要用到对与二进制数的移位操作。虽然在C++中很常见,但是在C语言和matlab中并不常用,特此记之。

12. Integer to Roman

题目:
Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.
思路:一位一位地输出即可。
代码:

class Solution(object):    def intToRoman(self, num):        """        :type num: int        :rtype: str        """        Dic1={ 0:"",1:"I",2:"II",3:"III",4:"IV",5:"V",6:"VI",7:"VII",8:"VIII",9:"IX"}        Dic2={0:"",1:"X",2:"XX",3:"XXX",4:"XL",5:"L",6:"LX",7:"LXX",8:"LXXX",9:"XC"}        Dic3={0:"",1:"C",2:"CC",3:"CCC",4:"CD",5:"D",6:"DC",7:"DCC",8:"DCCC",9:"CM"}        Dic4={0:"",1:"M",2:"MM",3:"MMM"}        roman=""        roman+=Dic4[int(num / 1000) % 10]        roman+=Dic3[int(num / 100) % 10]        roman+=Dic2[int(num / 10) % 10]        roman+=Dic1[num % 10]        return roman

287. Find the Duplicate Number

题目:
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

Note:
You must not modify the array (assume the array is read only).
You must use only constant, O(1) extra space.
Your runtime complexity should be less than O(n2).
There is only one duplicate number in the array, but it could be repeated more than once.
思路:在做过了前面的通过移位算法来判断是否存在重复字符的题目之后,这道题用相同的方式来处理即可。虽然leetcode上将此题定位Hard级别,但是其实实现起来,相当简单。
代码:

class Solution(object):    def findDuplicate(self, nums):        """        :type nums: List[int]        :rtype: int        """        N=0        for i in nums:            N1=N>>i            if N1%2==1:                return i            else:                N+=1<<i        return

328. Odd Even Linked List

题目:
Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes.

You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity.

Example:
Given 1->2->3->4->5->NULL,
return 1->3->5->2->4->NULL.

Note:
The relative order inside both the even and odd groups should remain as it was in the input.
The first node is considered odd, the second node even and so on …
思路:用两个点存储奇数和偶数的表头,并进行交换和更新。
代码:

# Definition for singly-linked list.# class ListNode(object):#     def __init__(self, x):#         self.val = x#         self.next = Noneclass Solution(object):    def oddEvenList(self, head):        """        :type head: ListNode        :rtype: ListNode        """        if head is None: return head        odd = oddHead = head        even = evenHead = head.next        while even and even.next:            odd.next = even.next            odd = odd.next            even.next = odd.next            even = even.next        odd.next = evenHead        return oddHead

230. Kth Smallest Element in a BST

题目:
Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.

Note:
You may assume k is always valid, 1 ≤ k ≤ BST’s total elements.

Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?

Hint:

Try to utilize the property of a BST.
What if you could modify the BST node’s structure?
The optimal runtime complexity is O(height of BST).
思路:利用二叉树的中序遍历,递增地访问二叉树的节点。
代码:

# Definition for a binary tree node.# class TreeNode:#     def __init__(self, x):#         self.val = x#         self.left = None#         self.right = Noneclass Solution:    def kthSmallest(self, root, k):        stack = []        node = root        while node:            stack.append(node)            node = node.left        x = 1        while stack and x <= k:            node = stack.pop()            x += 1            right = node.right            while right:                stack.append(right)                right = right.left        return node.val

337. House Robber III

题目:
The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the “root.” Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that “all houses in this place forms a binary tree”. It will automatically contact the police if two directly-linked houses were broken into on the same night.

Determine the maximum amount of money the thief can rob tonight without alerting the police.

Example 1:
3
/ \
2 3
\ \
3 1
Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
Example 2:
3
/ \
4 5
/ \ \
1 3 1
Maximum amount of money the thief can rob = 4 + 5 = 9.
思路:利用递归的思想,但是在递归时,每访问一个节点是,返回两个值。有点动态规划的意思,只不过备忘序列只有两个值而已。
代码:

class Solution(object):      def rob(self, root):          """         :type root: TreeNode         :rtype: int         """        def dfs(root) :              if not root : return [0, 0]              robLeft = dfs(root.left)              robRight = dfs(root.right)              norobCur = robLeft[1] + robRight[1]              robCur = max(robLeft[0] + robRight[0] + root.val, norobCur)              return [norobCur, robCur]          return dfs(root)[1] 

377. Combination Sum IV

题目:
Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target.

Example:

nums = [1, 2, 3]
target = 4

The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)

Note that different sequences are counted as different combinations.

Therefore the output is 7.
思路:这道题需要注意的是,数字相同,排列方式不同,也算是不同的组合方法。因此,一开始的迭代的思路必须明确这一点。而采用动态规划来减少运算量几乎在这类问题中是一种标配了。
我自己写的代码:

class Solution(object):    def combinationSum4(self, nums, target):        """        :type nums: List[int]        :type target: int        :rtype: int        """        if target<0:                return 0        if target==0:                return 1        if not nums:            return 0        nums_min=min(nums)        count=0        for i in nums:            count+=(1<<i)        dp=[1*(i==0) for i in range(target+1)]        ret=0        for i in range(1,int(target/nums_min)+1):            for j in range(target,nums_min*i-1,-1):#前i个数中,和为j的组合的个数,最小为nums_min*个数                ret_ij=0                for k in range(j):                    ret_ij+=dp[k]*((count>>(j-k))&1)                   # print([i,j,k,ret_ij])                dp[j]=ret_ij            dp[nums_min*i:nums_min*(i-1):-1]=[0]*nums_min            #print('操作完成',dp)            ret+=dp[-1]#前i个数中,和为target的组合的个数        return ret

结果当然是超时,运算量太大了。

然后搜索别人的代码:

class Solution(object):      def combinationSum4(self, nums, target):          nums.sort()        res = [0] * (target+1)          res[0] = 1  #res中记录和为j的组合的个数        for i in range(1,target+1):  #从和为1的组合的个数开始计算。            t = 0              for j in nums:                  if j > i: #依次将j加入到队列中, 计算和为i的组合的个数。                    break                  t += res[i-j]              res[i] = t          return res[-1]# 权值更新

发现,果然一开始思路就跑偏了,理解题目出错,没注意到其实不同的排序算不同的解法,自己把问题想得太复杂。结果算法变得复杂无比。看别人的代码,才觉得,真实简洁优雅。

231. Power of Two

题目:
Given an integer, write a function to determine if it is a power of two.
代码:

import mathclass Solution(object):    def isPowerOfTwo(self, n):        """        :type n: int        :rtype: bool        """        if n<=0:            return False        else:            return n==pow(2,round(math.log(n,2)))

326. Power of Three

题目:
Given an integer, write a function to determine if it is a power of three
代码:

import mathclass Solution(object):    def isPowerOfThree(self, n):        """        :type n: int        :rtype: bool        """        if n<=0:            return False        else:            return n==pow(3,round(math.log(n,3)))     

202. Happy Number

题目:
Write an algorithm to determine if a number is “happy”.

A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.

Example: 19 is a happy number

1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
思路:
首先,多个数的平房和很快会收敛到100以内。那么只需要在100以内考虑就行了。数字大于100时,简单的迭代就会让数减小到100以内。
在100以内,找出所有的快乐数,并建立表。如果数字到了100以内,而仍然不是快乐数,那么它就不肯能再是快乐数了。

代码:

class Solution(object):    def isHappy(self, n):        """        :type n: int        :rtype: bool        """        nothappy=[ 4,16,37,58 ,89 ,145 ,42 , 20 ,4]        happy=[1, 7, 10, 13, 19, 23, 28, 31, 32, 44, 49, 68, 70, 79, 82, 86, 91, 94, 97, 100]        if nothappy.count(n)>0:            return False        if n<=100 and happy.count(n)==0:            return False        if happy.count(n)>0:            return True        squaresum=0        while n>0:            squaresum+=(n%10)**2            n=int(n/10)        return self.isHappy(squaresum)

至此,leetcode上面的题目已经刷完40道。在刷题过程中,发现根据AC率来选题,并不能反映题目的难度。很多难度大的题目,可能提交人数就很少,所以AC率很高。这样来做题目,对新手来说,不是一个很好的选择。根据leetcode定的难易程度来选择题目会是一个更好的选择。

在刷题过程中,发现思路总是比代码能力重要。有了好的思路,一道题目很简单就解决了。这也就是算法在编程中的作用了。

在python学习的整个流程中,初级阶段就先到此结束了。接下来的阶段,将会把重心放到python语言的更加高层次的特性的学习上。算法题目的编程将会在这段时间成为空余时间的消遣了。

0 0
原创粉丝点击