python练习(十四)

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

Permutations II

题目

Given a collection of numbers that might contain duplicates, return all possible unique permutations.

For example,
[1,1,2] have the following unique permutations:
[
[1,1,2],
[1,2,1],
[2,1,1]
]

思路与解答

返回所有的可能排列,这要返回多少啊
怎么才能花式排列呢。。。是啊,怎么花式排列呢
dfs?
for加dfs
bfs。。。没必要
。。。怎么去掉自己呢,花式排列还不对
成为全排序,还要去重
set方法是我用错了吗,感觉自己用了一个很耗时的方法

class Solution(object):
    def __init__(self):
        self.res = []
    def permuteUnique(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        def dfs(l,g):
            if len(l) == len(nums):
                if l not in self.res:
                    self.res.append(l)
            for i,v in enumerate(nums):
                if i not in g:
                    dfs(l+[v],g+[i])
        dfs([],[])
        return self.res

然后就超时了
突然发现dfs忘写return了,加上之后单测可以,提交又超时了
所以想办法把list换成dict?

class Solution(object):
    def __init__(self):
        self.res = []
    def permuteUnique(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        d={}
        for i in nums:
            if i in d:
                d[i] += 1
            else:
                d[i] = 1

        def dfs(l,x):
            g = x.copy()
            if not g:
                if l not in self.res:
                    self.res.append(l)
                return
            for (k,v) in g.items():
                if v > 0:
                    g[k] -= 1
                    print g,x,l,l+[k]
                    #if not g[k]:del g[k]
                    dfs(l+[k],g)
        dfs([],d)
        return self.res
'''
  g              x         l  l+[k]
{1: 1, 2: 1} {1: 2, 2: 1} [] [1]
{1: 0, 2: 1} {1: 1, 2: 1} [1] [1, 1]
{1: 0, 2: 0} {1: 0, 2: 1} [1, 1] [1, 1, 2]
{1: 0, 2: 0} {1: 1, 2: 1} [1] [1, 2]
{1: 1, 2: 0} {1: 2, 2: 1} [] [2]
{1: 0, 2: 0} {1: 1, 2: 0} [2] [2, 1]
'''

理论上x-g=l+[k]-l=[k]
前三行倒是做到了,第四行,开启第二循环的第一步时就跪了。

class Solution(object):
    def __init__(self):
        self.res = []
    def permuteUnique(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        d={}
        for i in nums:
            if i in d:
                d[i] += 1
            else:
                d[i] = 1

        def dfs(l,x,n): 
            if not x:
                if l not in self.res:
                    self.res.append(l)
                return
            for (k,v) in x.items():
                g=x.copy()
                g[k] -= 1
                if not g[k]:del g[k]
                dfs(l+[k],g,n+1)
        dfs([],d,0)
        return self.res

经过不断的测试,我发现我应该在每个dfs函数生成前给它们创建一个dict,而不是在函数生成后新建一个。
然后我这次提交的时候忘记把测试时使用的n去掉,结果252ms,2.5%?
我去掉n之后就130ms,30%了(再次测试带n的就135ms了….)
如果有更好的去重我才能会更快(从源头上去重而不是结尾)

答案

class Solution(object):
    def permuteUnique(self, nums):
        ans = [[]]
        for n in nums:
            new_ans = []
            for l in ans:
                for i in xrange(len(l)+1):
                    new_ans.append(l[:i]+[n]+l[i:])
                    if i<len(l) and l[i]==n: break              #handles duplication
            ans = new_ans
        return ans

100ms版本
new_ans.append(l[:i]+[n]+l[i:])这句是将n插入到new_ans内的各个list中的不同位置,从头到尾一遍,当要插入的位置的数字与插入数字n相同,且不是最后一位时,跳出该循环,哦,两层循环都跳出去了,直接到ans那句了。
想了半天,如果出现了l[i]==n的,情况,相当于以前插入过与n相同的值,如果继续插入必然重复,以l[i]==n为分界线,分界线之前的由当前循环掌控,之后的由其它循环掌控

 return reduce(lambda a,n:[l[:i]+[n]+l[i:]for l in a for i in xrange((l+[n]).index(n)+1)],nums,[[]])

92ms,心里苦啊
xrange((l+[n]).index(n)+1)哦吼

Reverse Words in a String III

题目

Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order.

Example 1:
Input: “Let’s take LeetCode contest”
Output: “s’teL ekat edoCteeL tsetnoc”
Note: In the string, each word is separated by single space and there will not be any extra space in the string.

思路与解答

easy难度的哦,
sqlit函数。。。好像不太对
哦,split

return ' '.join([i[::-1] for i in s.split()])

so easy

答案

#在这里我首先反转单词的顺序,然后反转整个字符串。
def reverseWords(self, s):
    return ' '.join(s.split()[::-1])[::-1]

有意思

0.79 0.78 0.80 0.82 0.79 seconds for: ' '.join(s.split()[::-1])[::-1]
2.10 2.14 2.08 2.06 2.13 seconds for: ' '.join(x[::-1] for x in s.split())
1.27 1.26 1.28 1.28 1.26 seconds for: ' '.join([x[::-1] for x in s.split()])

双重反转速度还要快些,加个方括号的第三种比不加的还要块一点。

Implement Stack using Queues

题目

Implement the following operations of a stack using queues.

push(x) – Push element x onto stack.
pop() – Removes the element on top of the stack.
top() – Get the top element.
empty() – Return whether the stack is empty.
Notes:
You must use only standard operations of a queue – which means only push to back, peek/pop from front, size, and is empty operations are valid.
Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue.
You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack).

思路与解答

还是easy难度的
队列模仿堆栈。。。两个队列再怎么倒腾,还是一样的啊,除非能判断队列是否就剩一个元素了。
压一个数生成一个队列?。。。过分了
能获取队列长度啊
挺简单的,不贴代码了
就是测试里为什么一定要把pop打出来?

答案

class MyStack {

    private Queue queue;

    public void push(int x) {
        Queue q = new LinkedList();     // could be any queue type, see note above
        q.add(x);
        q.add(queue);
        queue = q;
    }

    public void pop() {
        queue.remove();
        queue = (Queue) queue.peek();
    }

    public int top() {
        return (int) queue.peek();
    }

    public boolean empty() {
        return queue == null;
    }
}

非常有想法的回答,确实做到了O(1),厉害了
虽然不是使用python写的吧
思路是生成一个空队列,这没什么好说的
在push的时候,生成一个链表q,链表的值保存为x,而链表的第二个值存储为原队列,将q视为新队列…..嗯。。。链表也能假装自己是队列吗
pop的时候将第一个值取出,再把第二个值取出来成为链表
top就peek
空就空
python也能做到的

重写

class MyStack(object):

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.queue=collections.deque()

    def push(self, x):
        """
        Push element x onto stack.
        :type x: int
        :rtype: void
        """
        q = []
        q.append(x)
        q.append(self.queue)
        self.queue = collections.deque(q)

    def pop(self):
        """
        Removes the element on top of the stack and returns that element.
        :rtype: int
        """
        x = self.queue.popleft()
        self.queue = self.queue.popleft()
        return x

    def top(self):
        """
        Get the top element.
        :rtype: int
        """
        return self.queue[0]

    def empty(self):
        """
        Returns whether the stack is empty.
        :rtype: bool
        """
        return len(self.queue) == 0


# Your MyStack object will be instantiated and called as such:
# obj = MyStack()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.top()
# param_4 = obj.empty()

从38ms提升到35ms。。。

Excel Sheet Column Number

题目

Given a column title as appear in an Excel sheet, return its corresponding column number.

For example:

A -> 1
B -> 2
C -> 3
...
Z -> 26
AA -> 27
AB -> 28 

思路与解答

???
啥意思
好像是给A就返回1,依次类推
嗯。。相当于26进制的数啊

class Solution(object):
    def titleToNumber(self, s):
        """
        :type s: str
        :rtype: int
        """
        ssum = 0
        for k,v in enumerate(s[::-1]):
            ssum += (26**k)*(ord(v)-64)
        return ssum

42ms
不过我可以改成一行的

return sum([(26**k)*(ord(v)-64) for k,v in enumerate(s[::-1])])

32ms,100%
这里写图片描述
第一次见到100%啊
(虽然第二遍45ms,划掉)
(第三遍39ms)

答案

return reduce(lambda x, y: 26*x+ord(y)-64, s, 0)

有趣。。。这份代码也提交出一份100%的

Subarray Sum Equals K

题目

Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.

Example 1:
Input:nums = [1,1,1], k = 2
Output: 2
Note:
The length of the array is in range [1, 20,000].
The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].

思路与解答

不再是easy难度的了
为什么这道题是如此的熟悉?
第一次是dfs超时,使用队列
第二次是队列不好做,使用dfs
这次估计还是队列好
哦哦哦,连续子数组,不一样,但是又和连续子数组扯上关系了
这样看,重点是连续子数组
起点怎么办

class Solution(object):
    def subarraySum(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        ssum = 0
        ss = 0
        os = 0
        for i,v in enumerate(nums):
            ss += v
            while ss > k and os <= i:
                ss -= nums[os]
                os += 1
            if ss == k:
                ssum +=1
        return ssum

k值居然有0的,不能特例,好像题目也没说非负
不对啊,有负数我起点又有问题了,万一k值就是负数呢?也没说不行吧
心塞
相对距离喽。。。
感觉漏洞蛮大的
感觉要崩
二重循环稳死的,不要想了

答案

    def subarraySum(self, nums, k):

        sums = {0:1} # prefix sum array
        res = s = 0
        for n in nums:
            s += n # increment current sum
            res += sums.get(s - k, 0) # check if there is a prefix subarray we can take out to reach k
            sums[s] = sums.get(s, 0) + 1 # add current sum to sum count
        return res

感谢
将从0到i的和统统存放在字典里
当前之和为s
如果字典里存在s-k,则说明能够取一截数组使其之和为k
若sum[s-k]值为n,则说明有n个连续子数组之和为k

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值