python练习(十五)

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

Clone Graph

题目

Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.

OJ’s undirected graph serialization:
Nodes are labeled uniquely.

We use # as a separator for each node, and , as a separator for node label and each neighbor of the node.
As an example, consider the serialized graph {0,1,2#1,2#2,2}.

The graph has a total of three nodes, and therefore contains three parts as separated by #.

First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
Second node is labeled as 1. Connect node 1 to node 2.
Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.

思路与解答

所以怎么克隆?
哦,传入的是那个,返回啥?

        n = node
        return n
#Node with label -1 was not copied but a reference to the original one.

哎呦我去居然被发现了

class Solution:
    # @param node, a undirected graph node
    # @return a undirected graph node
    def cloneGraph(self, node):
        if not node:return node
        def dfs(n):
            new = UndirectedGraphNode(n.label)
            for i in n.neighbors:
                new.neighbors.append(dfs(n))
            return new
        return dfs(node)

没有run只有提交好烦
应该是和我的想法不一样吧

答案

class Solution:
    # @param node, a undirected graph node
    # @return a undirected graph node
    def cloneGraph(self, node):
        if not node:
            return node
        root = UndirectedGraphNode(node.label) #一个实例
        stack = [node]  #一个列表
        visit = {}  #一个字典
        visit[node.label] = root  #key值为label,v值为实例地址?
        while stack:    #当这个列表不为空的时候
            top = stack.pop()    #取出列表的一个元素(实例)

            for n in top.neighbors:   #实例的neighbors
                if n.label not in visit:   #如果该实例没有被访问过
                    stack.append(n)         #为stact中添加该实例
                    visit[n.label] = UndirectedGraphNode(n.label)  #在visit字典中存入该实例信息
                visit[top.label].neighbors.append(visit[n.label])  #在对应复制体neighbors添加对应实例

        return root  

大致明白了

重写

class Solution:
    # @param node, a undirected graph node
    # @return a undirected graph node
    def cloneGraph(self, node):
        if not node:return node
        visit = {} 
        def dfs(n,v):
            new = UndirectedGraphNode(n.label)
            visit[node.label] = new
            for i in n.neighbors:
                if i.label in v.keys():
                    new.neighbors.append(v[i.label])
                else:   
                    new.neighbors.append(dfs(n,v))
            return new
        return dfs(node,visit)

Range Addition II

题目

Given an m * n matrix M initialized with all 0’s and several update operations.

Operations are represented by a 2D array, and each operation is represented by an array with two positive integers a and b, which means M[i][j] should be added by one for all 0 <= i < a and 0 <= j < b.

You need to count and return the number of maximum integers in the matrix after performing all the operations.

Example 1:
Input:
m = 3, n = 3
operations = [[2,2],[3,3]]
Output: 4
Explanation:
Initially, M =
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]

After performing [2,2], M =
[[1, 1, 0],
[1, 1, 0],
[0, 0, 0]]

After performing [3,3], M =
[[2, 2, 1],
[2, 2, 1],
[1, 1, 1]]

So the maximum integer in M is 2, and there are four of it in M. So return 4.
Note:
The range of m and n is [1,40000].
The range of a is [1,m], and the range of b is [1,n].
The range of operations size won’t exceed 10,000.

思路与解答

easy的
感觉数学上处理好的话根本不需要去给M加数啊
事实上M也没给出实例

class Solution(object):
    def maxCount(self, m, n, ops):
        """
        :type m: int
        :type n: int
        :type ops: List[List[int]]
        :rtype: int
        """
        if not ops: return m*n
        h,w = m,n
        for i in ops:
            h = min(i[0],h)
            w = min(i[1],w)
        return h*w

答案

        return min(op[0] for op in ops)*min(op[1] for op in ops)if ops else m*n

更简洁的写法

def maxCount(self, R, C, ops):
    if not ops: return R * C
    X, Y = zip(*ops)
    return min(X) * min(Y)

zip写法

return min(ops, key=lambda e: e[0])[0] * min(ops, key=lambda e: e[1])[1] if ops else m * n

Single Number III

题目

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

Note:
The order of the result is not important. So in the above example, [5, 3] is also correct.
Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

思路与解答

很面熟嘛,稍微一改就medium了吗
异或方案肯定是不行了,但是我那个字典的正好可以啊,我觉得都不需要改动的

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        dic = {}
        for num in nums:
            if num in dic:
                del dic[num]
            else:
                dic[num] = 1
        return list(dic.keys())

怪不得我之前list()一直不能用,我之前一直加的是方括号没注意!!!
52ms,23%,还好
虽然无法恒定空间复杂性就是了

答案

class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        xor = 0
        a = 0
        b = 0
        for num in nums:
            xor ^= num
        mask = 1
        while(xor&mask == 0):#使xor和mask有一个相同位置的1
            mask = mask << 1
        for num in nums:
            if num&mask:
                a ^= num
            else:
                b ^= num
        return [a, b]

不好懂
解释:
只出现一次的两个数字有所不同,这是我们如何区分它们。否则,它们将是重复的数字之一。

一个重要的一点是,通过对所有数字进行异或,我们实际得到两个目标数字的异或(因为XORing两个重复数总是导致0)。考虑两个目标数的XOR结果; 如果XOR结果的某一位为1,则表示该位置上的两个目标数字不同。

让我们说,在第i位,两个所需的数字彼此不同。这意味着一个数字的位i等于0,另一个数字的位i等于1。

因此,所有的数字可以根据位置i的位分成两组。
第一组由i的位数为0
的所有数字组成。第二组由i位为1的所有数字组成。

请注意,如果重复的数字位i为0,那么它的两个副本将属于第一个组。类似地,如果重复的数字的位i为1,那么它的两个副本将属于第二个组。

通过XoRing所有数字在第一组,我们可以得到第一个数字。
通过XoRing第二组中的所有数字,我们可以得到第二个数字。

Rotate Image

题目

You are given an n x n 2D matrix representing an image.

Rotate the image by 90 degrees (clockwise).

Follow up:
Could you do this in-place?

思路与解答

zip?
怎么翻转成转动90度还要研究下
可以先将矩阵到过来就可以了

        matrix[:] = zip(*matrix[::-1])

完成(不过zip返回的内部不是元组吗,怎么就过了呢)

答案

class Solution:
    def rotate(self, A):
        n = len(A)
        for i in range(n/2):
            for j in range(n-n/2):
                A[i][j], A[~j][i], A[~i][~j], A[j][~i] = \
                         A[~j][i], A[~i][~j], A[j][~i], A[i][j]

手动旋转方案

A[:] = map(list, zip(*A[::-1]))

去除元组方案

class Solution:
    def rotate(self, A):
        n = len(A)
        for i in range(n/2):
            for j in range(n-n/2):
                for _ in '123':
                    A[i][j], A[~j][i], i, j = A[~j][i], A[i][j], ~j, ~i
                i = ~j

快速方案

class Solution:
    def rotate(self, A):
        A.reverse()
        for i in range(len(A)):
            for j in range(i):
                A[i][j], A[j][i] = A[j][i], A[i][j]

快速方案二

Distribute Candies

题目

Given an integer array with even length, where different numbers in this array represent different kinds of candies. Each number means one candy of the corresponding kind. You need to distribute these candies equally in number to brother and sister. Return the maximum number of kinds of candies the sister could gain.

Example 1:
Input: candies = [1,1,2,2,3,3]
Output: 3
Explanation:
There are three different kinds of candies (1, 2 and 3), and two candies for each kind.
Optimal distribution: The sister has candies [1,2,3] and the brother has candies [1,2,3], too.
The sister has three different kinds of candies.
Example 2:
Input: candies = [1,1,2,3]
Output: 2
Explanation: For example, the sister has candies [2,3] and the brother has candies [1,1].
The sister has two different kinds of candies, the brother has only one kind of candies.
Note:

The length of the given array is in range [2, 10,000], and will be even.
The number in given array is in range [-100,000, 100,000].

思路与解答

这道题问法有些奇怪,好像有些奇怪的思路需要验证一下

        ls,lc = len(set(candies)),len(candies)
        return lc/2 if ls >= lc/2 else ls

一行写起来太难看了

答案

    return min(len(candies) / 2,len(set(candies)))

又蠢了

下一期暂时为最后一期,剩下的等这段时间过去再说

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值