python练习(十一)

来源:互联网 发布:微信怎么发淘宝联盟 编辑:程序博客网 时间:2024/05/22 15:54

  • Number of Boomerangs
    • 题目
    • 思路与解答
    • 答案
      • 重写
      • tips
  • Pascals Triangle
    • 题目
    • 思路与解答
    • 答案
      • 重写
  • Pascals Triangle II
    • 题目
    • 思路与解答
    • 答案
  • Remove Duplicates from Sorted List
    • 题目
    • 思路与解答
    • 答案
  • Power of Four
    • 题目
    • 思路与解答
    • 答案

注意,答案只是代表是他人写的代码,正确,但不一定能通过测试(比如超时),列举出来只是它们拥有着独到之处,虽然大部分确实比我的好

Number of Boomerangs

题目

Given n points in the plane that are all pairwise distinct, a “boomerang” is a tuple of points (i, j, k) such that the distance between i and j equals the distance between i and k (the order of the tuple matters).

Find the number of boomerangs. You may assume that n will be at most 500 and coordinates of points are all in the range [-10000, 10000] (inclusive).

Example:
Input:
[[0,0],[1,0],[2,0]]

Output:
2

Explanation:
The two boomerangs are [[1,0],[0,0],[2,0]] and [[1,0],[2,0],[0,0]]

思路与解答

感觉可不太好做,两重遍历肯定是能做出来的,不过绝对不是一个好主意
所以呢。。。
记录点于点之间的距离,怕不是还是要遍历
扫了眼讨论区,都是O(n^2)的,遍历吧

from collections import Counterclass Solution(object):    def numberOfBoomerangs(self, points):        """        :type points: List[List[int]]        :rtype: int        """        l=[]        ssum =0        for i in points:            l.append([((i[0]-j[0])**2+(i[1]-j[1])**2)**0.5 for j in points])        for x in l:            s = Counter(x)            for ss in s.values():                ssum += ss*(ss-1)        return ssum

不出意料的超时了

使用字典,但是忘记每次循环清空字典了,尴尬

from collections import defaultdictclass Solution(object):    def numberOfBoomerangs(self, points):        """        :type points: List[List[int]]        :rtype: int        """        d = defaultdict(int)        ssum =0        for i in points:            d.clear()            for j in points:                x = ((i[0]-j[0])**2+(i[1]-j[1])**2)**0.5                d[x] +=1                ssum +=(d[x]-1)*2        return ssum

通过了哈哈哈
1500ms,26%

答案

class Solution(object):    def numberOfBoomerangs(self, points):        length = len(points)        res = 0        for p1 in points:            D = dict()            for p2 in points:                distance = (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2                if(distance in D):                    res += D[distance]                    D[distance] += 2                else:                    D[distance] = 2        return res

别人的600+ms的
…看起来和我的差不多嘛…

重写

莫非是defaultdict的问题?还是clear的问题?
不是clear 的问题
去掉defaultdict下降到1100ms了,还是不够
诶?才发现它没有开根号的操作!!!是啊,不需要
下降到800+ms
只有在d[x]大于1的时候才需要进行相加

class Solution(object):    def numberOfBoomerangs(self, points):        """        :type points: List[List[int]]        :rtype: int        """        ssum =0        for i in points:            d = {}            for j in points:                x = (i[0]-j[0])**2+(i[1]-j[1])**2                if x in d:                    d[x] +=1                    ssum +=(d[x]-1)*2                else:                    d[x] = 1                   return ssum

666ms差不多了(虽然看到100+ms的java与300ms的c++)
多重循环里的每一句话都有深思啊

tips

关于x**2与x*x在py2与py3的区别

Pascal’s Triangle

题目

Given numRows, generate the first numRows of Pascal’s triangle.

For example, given numRows = 5,
Return

[     [1],    [1,1],   [1,2,1],  [1,3,3,1], [1,4,6,4,1]]

思路与解答

这不是杨辉三角嘛
所以怎么通过层数生成相应的list呢(好像这个也有作弊方法啊,就是不知道最大几层)

l=[]        n=0        while n < numPows:            l.append()            n += 1        return l 

函数主体肯定是这样的

class Solution(object):    def generate(self, numRows):        """        :type numRows: int        :rtype: List[List[int]]        """        l=[]        if numRows:l=[[1]]        n=1        while n < numRows:            l2 = [0]+l[n-1]+[0]            l.append([l2[i]+l2[i+1] for i in range(n+1)])             n += 1        return l 

通过
39ms ,40%可以接受

答案

def generate(numRows):    pascal = [[1]*(i+1) for i in range(numRows)]    for i in range(numRows):        for j in range(1,i):            pascal[i][j] = pascal[i-1][j-1] + pascal[i-1][j]    return pascal

我还以为这样的会比较慢呢,比我的还快一点

def generate(self, numRows):        res = [[1]]        for i in range(1, numRows):            res += [map(lambda x, y: x+y, res[-1] + [0], [0] + res[-1])]        return res[:numRows]

求杨辉三角时使用了非常棒的思路
return 的方式也非常棒,光是这一点就能让我减少不少代码
话说这个lambda函数和operator.add功能一样把,可以替换吧
可以替换

重写

class Solution(object):    def generate(self, numRows):        """        :type numRows: int        :rtype: List[List[int]]        """        l=[[1]]        for n in range(numRows-1):            l2 = [0]+l[n]+[0]            l.append([l2[i]+l2[i+1] for i in range(n+2)])         return l[:numRows] 

虽然时间没有什么变化,但是代码短了啊

Pascal’s Triangle II

题目

Given an index k, return the kth row of the Pascal’s triangle.

For example, given k = 3,
Return [1,3,3,1].

Note:
Could you optimize your algorithm to use only O(k) extra space?

思路与解答

唔。。。

class Solution(object):    def getRow(self, rowIndex):        """        :type rowIndex: int        :rtype: List[int]        """        l=[[1]]        for n in range(rowIndex):            l2 = [0]+l[n]+[0]            l.append([l2[i]+l2[i+1] for i in range(n+2)])         return l[rowIndex] 

52ms,9%有点慢啊

class Solution(object):    def getRow(self, rowIndex):        """        :type rowIndex: int        :rtype: List[int]        """        l=[[1]]        for n in range(rowIndex):            l += [map(operator.add, l[-1] + [0], [0] + l[-1])]        return l[rowIndex] 

这种确实比我的要快啊

答案

class Solution(object):    def getRow(self, rowIndex):        """        :type rowIndex: int        :rtype: List[int]        """        l=[1]        for n in range(rowIndex):            l = [x + y for x, y in zip([0]+l, l+[0])]        return l

据说这种方法比map要快30%,但是很不幸,在我的电脑上做不到这点多次测试大概快了不到8%(2/35)

Remove Duplicates from Sorted List

题目

Given a sorted linked list, delete all duplicates such that each element appear only once.

For example,
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.

思路与解答

…sorted()
哎呀,是个链表

class Solution(object):    def deleteDuplicates(self, head):        """        :type head: ListNode        :rtype: ListNode        """        l=[]        on=n=head        while n != None:            if n.val not in l:                l.append(n.val)                on = n                n = n.next            else:                n = on.next = n.next        return head

50%可以接受

答案

def deleteDuplicates(self, head):        """        :type head: ListNode        :rtype: ListNode        """        cur = head        while cur and cur.next:            if cur.val == cur.next.val:                cur.next = cur.next.next            else:                cur = cur.next        return head

感觉确实要好一些

Power of Four

题目

Given an integer (signed 32 bits), write a function to check whether it is a power of 4.

Example:
Given num = 16, return true. Given num = 5, return false.

Follow up: Could you solve it without loops/recursion?

思路与解答

     if num%4:return False        while True:            if num < 4:                return False            elif num == 4:                return True            else:                num = num/4  

1也是4的幂,好吧是的
加上1的判断之后还是有问题
最开始除4没有余数不代表之后也没有哦
不应该把*1.0删除的

class Solution(object):    def isPowerOfFour(self, num):        """        :type num: int        :rtype: bool        """        if num==1:return True        if num%4:return False        while True:            if num < 4:                return False            elif num == 4:                return True            num = num*1.0/4            if num != int(num):                return False

58ms10%有些不对了啊

答案

class Solution(object):    def isPowerOfFour(self, num):        """        :type num: int        :rtype: bool        """        '''        若一个整数是4的幂,则其二进制形式具有如下特点:        1. 最高位为1,其余位为0  ---- 用num & (num - 1) == 0 判断        2. 0的个数为偶数        ----  用num & 0x55555555 > 0 判断        There are even # of 0's, so 1 must be in the odd position.        '''        return num > 0 and num & (num - 1) == 0 and num & 0x55555555 != 0

唔。。。

        return num & (num - 1) == 0 and num & 0x55555555 != 0

查看讨论区发现第一个判断包含在其它两个判断里了,不需要再进行判断了

return num > 0 && (num & (num - 1)) == 0 && (num - 1) % 3 == 0;

另外一种有趣的思路(注意,这个不是python语言的)
证明#1:(4 ^ n-1)=(4-1)(4 ^(n-1)+ 4 ^(n-2)+ 4 ^(n-3)+ ….. + 4 + 1)

证明#2(通过感应)4 ^(n + 1)-1 = 4 4 ^ n -1 = 3 4 ^ n + 4 ^ n-1。第一个被除以3,第二个被归纳假设证明

首先,任何数字通过“n ^(n-1)== 0”必须是2的幂。
其次,上述所有数字可以进一步分类为2类。A:所有数字为2 ^(2k + 1),B:所有数字为2 ^(2k)。
第三,我们可以看出,2 ^(2k + 1)-1不能通过(n-1)%3 == 0的测试。(通过感应)所以所有A被排除,只剩下B,这是4的幂。

原创粉丝点击