python练习(九)

来源:互联网 发布:怎么注册淘宝账号 编辑:程序博客网 时间:2024/05/29 18:06

  • Length of Last Word
    • 题目
    • 思路解答
    • 答案
  • Minimum Index Sum of Two Lists
    • 题目
    • 思路
    • 解答
    • 答案
  • Minimum Moves to Equal Array Elements
    • 题目
    • 思路
    • 解答
    • 答案
      • 前人种树
  • Contains Duplicate II
    • 题目
    • 思路与解答
    • 答案
  • Missing Number
    • 题目
    • 解答
    • 答案

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

Length of Last Word

题目

Given a string s consists of upper/lower-case alphabets and empty space characters ’ ‘, return the length of last word in the string.

If the last word does not exist, return 0.

Note: A word is defined as a character sequence consists of non-space characters only.

For example,
Given s = “Hello World”,
return 5.

思路&解答

class Solution(object):    def lengthOfLastWord(self, s):        """        :type s: str        :rtype: int        """        return  (len(s) - s.rfind(' ')-1) if s.rfind(' ') != -1 else 0

本来想以一行结束的,结果发现还有结尾是空格的选项,那就加上rstrip()就好了

return  (len(s.rstrip()) - s.rstrip().rfind(' ')-1) if s.rstrip().rfind(' ') != -1 else 0

结果检测的时候发现,还有包括只有一个单词的时候,算了,不要一行了

        return  (len(s.rstrip()) - s.rstrip().rfind(' ')-1) if s.rstrip().rfind(' ') != -1 else len(s.rstrip())

还是一行,哈哈,没想到吧

答案

return len(s.strip().split(' ')[-1])

哦,感觉自己是个傻屌,光想着去右空格了,怎么就忘了字符串的切分了呢…

唉python再快都是25ms起步
java,c++都是0ms,4ms这样的

Minimum Index Sum of Two Lists

题目

Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite restaurants represented by strings.

You need to help them find out their common interest with the least list index sum. If there is a choice tie between answers, output all of them with no order requirement. You could assume there always exists an answer.

Example 1:
Input:
[“Shogun”, “Tapioca Express”, “Burger King”, “KFC”]
[“Piatti”, “The Grill at Torrey Pines”, “Hungry Hunter Steakhouse”, “Shogun”]
Output: [“Shogun”]
Explanation: The only restaurant they both like is “Shogun”.
Example 2:
Input:
[“Shogun”, “Tapioca Express”, “Burger King”, “KFC”]
[“KFC”, “Shogun”, “Burger King”]
Output: [“Shogun”]
Explanation: The restaurant they both like and have the least index sum is “Shogun” with index sum 1 (0+1).
Note:
The length of both lists will be in the range of [1, 1000].
The length of strings in both lists will be in the range of [1, 30].
The index is starting from 0 to the list length minus 1.
No duplicates in both lists.

思路

求交集?

解答

return [i for i in list1 if i in list2]

提交上去才发现理解错了题目,并非简单的求交集,还要根据顺序来
感觉要复杂起来了

class Solution(object):    def findRestaurant(self, list1, list2):        """        :type list1: List[str]        :type list2: List[str]        :rtype: List[str]        """        s=float('inf')        l=[""]        for k,v in enumerate(list1):            if v in list2:                if k + list2.index(v) < s:                    l=[""]                    s = k + list2.index(v)                    l[0] = v                elif k + list2.index(v) == s:                    l.append(v)        return l

长了那么多啊

15%啊

答案

class Solution(object):    def findRestaurant(self, list1, list2):        """        :type list1: List[str]        :type list2: List[str]        :rtype: List[str]        """        # Time: O(l1 + l2)        # Space: O(l1 + l2)        d_1 = {name: index for (index, name) in enumerate(list1)}        d_2 = {name: index for (index, name) in enumerate(list2)}        min_index = float('inf')        result = []        for name in list1:            if name in d_2:                index_sum = d_1[name] + d_2[name]                if index_sum < min_index:                    min_index = index_sum                    result = [name]                elif index_sum == min_index:                    result.append(name)        return result

思路是一样的,用没用字典速度会差这么多?
我本来考虑用字典的,但是由于发现不用也行就没有使用
大概是index比较慢吧

Minimum Moves to Equal Array Elements

题目

Given a non-empty integer array of size n, find the minimum number of moves required to make all array elements equal, where a move is incrementing n - 1 elements by 1.

Example:

Input:
[1,2,3]

Output:
3

Explanation:
Only three moves are needed (remember each move increments two elements):

[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]

思路

这题啥意思嘞

搜了下思路,咳咳

就结果论
sum + m * (n - 1) = x * n
推论:(如果有一步没有加到minNum上,显然不是好的一步)
x = minNum + m
结论:
sum - minNum * n = m

解答

class Solution(object):    def minMoves(self, nums):        """        :type nums: List[int]        :rtype: int        """        return sum(nums)-min(nums)*len(nums)

有一个良好的思路真是太重要了

答案

class Solution(object):    def minMoves(self, nums):        """        :type nums: List[int]        :rtype: int        """        nums.sort()        steps = 0        diff = 0        for i in range(len(nums)-1):            if nums[i] == nums[i+1] + steps:                continue            else:                nums[i+1] += steps                diff = nums[i+1] - nums[i]                steps += diff        return steps

这是一些其它做法,甚至说目的都是一样的,但是相比较而言,就显得比较愚蠢了(要不是看了别人清晰的思路,连愚蠢的机会都没有)
…由于代码读的时候感觉比较奇怪,便对其进行修改
for循环里面的if判断没有任何作用!!!
我把if…else删除,只保留else内的3句话,没有任何问题

前人种树

强力解决方案:TLE将除了最大元素之外的所有元素添加1。如果有多个最大元素,请忽略最大元素之一。只要有一个明确的最大和最小元素 - 即所有元素都不相同,重复上述。class Solution(object):    def minMoves(self, nums):        """        :type nums: List[int]        :rtype: int        """        c = 0        while True:            max1, min1 = max(nums), min(nums)            if max1 == min1:                break            idx, c = nums.index(max1), c+1            for i in range(len(nums)):                nums[i] = nums[i] + 1 if i != idx else nums[i]        return c改进的暴力解决方案:TLE而不是在每次迭代中增加1,而是以批量增加。找到最小和最大值。现在我们希望最小化赶上最大。所以我们对除了最大值之外的所有元素执行一批移动(最大 - 最小)。现在在上述步骤之后,最低限度会赶上最初的最大值,我们现在将有一个新的最大值。重复一遍,直到我们有所有相等的元素。class Solution(object):    def minMoves(self, nums):        """        :type nums: List[int]        :rtype: int        """        c = 0        while True:            max1, min1 = max(nums), min(nums)            if max1 == min1:                break            diff = max1 - min1            idx, c = nums.index(max1), c + diff            for i in range(len(nums)):                nums[i] = nums[i] + diff if i != idx else nums[i]        return c通过转换问题的最佳解决方案移动可以解释为:“将1添加到每个元素并从任何一个元素中减去一个元素”。sum(nums_new)= sum(nums)+(n-1):我们只增加(n-1)个元素1。将nums数组可视化为条形图,其中每个索引处的值是高度nums [i]的条形。我们正在寻找最小的移动,使所有的酒吧达到最终相同的高度。现在在初始状态下向所有的条添加1不会改变初始状态 - 它只是将初始状态均匀地移动1.这使我们有一个洞察力,即单次移动相当于从任何一个元素减去1以同等高度达成最终状态的目标。所以我们的新问题是找到达到最终状态的最小数量,其中所有的数字都相等,并且在每个移动中,我们从任何元素中减去1。最终状态必须是每个元素等于最小元素的状态。说我们使K动作达到最终状态。那么我们有等式,N * min(nums)= sum(nums) - K.class Solution(object):    def minMoves(self, nums):        """        :type nums: List[int]        :rtype: int        """        return sum(nums) - len(nums)*min(nums)解决方案使用排序数组将nums数组可视化为条形图,其中每个索引处的值是高度nums [i]的条形。对阵列进行排序,使得索引为0的条最小为高,索引N-1处的条最高。现在在第一次迭代中,进行一系列移动,使得索引0处的高度等于索引N-1处的高度。显然这需要nums [N-1] - nums [0]移动。这些移动后,索引N-2将最高,索引0仍将是最小值,nums [0]将与nums [N-1]相同。在下一次迭代中,让num [N-2] -nums [0]移动。在这个迭代之后,nums [0],nums [N-2]和nums [N-1]将是一样的。class Solution(object):    def minMoves(self, nums):        """        :type nums: List[int]        :rtype: int        """        nums.sort()        c = 0        for i in range(len(nums)-1, -1, -1):            if nums[i] == nums[0]:                break            c += nums[i] - nums[0]        return c

Contains Duplicate II

题目

Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.

思路与解答

感觉不是很难,怎么快速做呢
比如先通过index挑出重复的?比较位置关系?index会不会比较慢?先Counter一遍再index?也不会快吧,index还需要循环。
或者循环遍历?通过两重循环,第一遍为nums,第二遍为nums[i+1:i+k+1]?感觉不太好诶

两重循环的又双叒叕超时了

from collections import defaultdictclass Solution(object):    def containsNearbyDuplicate(self, nums, k):        """        :type nums: List[int]        :type k: int        :rtype: bool        """        if not nums or not k:return False        d = defaultdict(int)        for i in nums:            d[i] +=1        for k,v in d.items():            if v >= 2:                m=0                while m < v-1:                    if abs(nums.index(k)[m] - nums.index(k)[m+1]) <= k:                        return True        return False   

我去,输入[-1,-1],1, 炸了
还有负数啊
突然发现index返回的是一个数,而不是list???

from collections import defaultdictclass Solution(object):    def containsNearbyDuplicate(self, nums, k):        """        :type nums: List[int]        :type k: int        :rtype: bool        """        if not nums or not k:return False        d = defaultdict(int)        for i in nums:            d[i] +=1        for key,v in d.items():            if v >= 2:                m=0                l=[p for p,q in enumerate(nums) if q == key ]                while m < v-1:                    if abs(l[m] - l[m+1]) <= k:                        return True                    m += 1        return False

。。。关人家-1什么事,index返回的是个数字,m的自增也忘记写了,k值的变量名也命名重了,好意思说人家-1

答案

def containsNearbyDuplicate(self, nums, k):    dic = {}    for i, v in enumerate(nums):        if v in dic and i - dic[v] <= k:            return True        dic[v] = i    return False

看看别人的用法

Missing Number

题目

Given an array containing n distinct numbers taken from 0, 1, 2, …, n, find the one that is missing from the array.

For example,
Given nums = [0, 1, 3] return 2.

Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?

解答

看起来一遍循环稳定解决,不清楚是否有更快的方式

        if nums[-1] != len(nums):return len(nums)        return [i for i in range(len(nums)) if i != nums[i]][0]

输入居然是没排序的,也是…没说
加上个sorted就是了
然后就超时了

class Solution(object):    def missingNumber(self, nums):        """        :type nums: List[int]        :rtype: int        """        num, l = sorted(nums), len(nums)        if num[-1] != l:return l        return [i for i in range(l) if i != num[i]][0]

唔,取出来还是有用的
9%

        num, l = sorted(nums), len(nums)        for k,v in enumerate(num):            if v != k:                return k        return l

18%了,不保证是本身运行误差

答案

class Solution(object):    def missingNumber(self, nums):        """        :type nums: List[int]        :rtype: int        """        return (1+len(nums))*len(nums)/2 - sum(nums)

我怎么就没想到呢!!!

def missingNumber(self, nums):    return reduce(operator.xor, nums + range(len(nums)+1))

又一次看到了xor

原创粉丝点击