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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章