python练习(十一)

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

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 Counter
class 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 defaultdict
class 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的幂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值