• LeetCode每周记录-3


    给出一个数组,找出能由这个数组组成的最大水桶“容积”(即最矮边决定的容积)。自己写的两种方法都在倒数第二个test case上超时了,先贴上自己的方法:

    class Solution(object):
        def maxArea(self, height):
            """
            :type height: List[int]
            :rtype: int
            """
            totalLength = len(height)
            if totalLength <= 1:
                return 0
            currMaxArea = 0
            for i, _height1 in enumerate(height):
                for j, _height2 in enumerate(list(reversed(height))[0:-(i+1)]):
                    width = totalLength - i - j - 1
                    if _height2 >= _height1:
                        if width * _height1 >= currMaxArea:
                            currMaxArea = width * _height1
                        break
                    else:
                        if width * _height2 >= currMaxArea:
                            currMaxArea = width * _height2
            return currMaxArea
            

    思路是按从左到右的顺序去找“木板”能组成的最大“容积”,对一块“木板”来说,从离它最远的那块“木板”开始,如果那块“木板”比它高,则与当前最大容积比较,

    然后到下一块“木板”;如果最远的那块“木板”比它低的话,比较最大容积后还需继续往左找距离近一些的“木板”。在倒序且数组很大的test case下,这个方法超时了。

    这里再贴上别人的解答:

    class Solution(object):
        def maxArea(self, height):
            """
            :type height: List[int]
            :rtype: int
            """
            MAX = 0
            x = len(height) - 1
            y = 0
            while x != y:
                if height[x] > height[y]:
                    area = height[y] * (x - y)
                    y += 1
                else:
                    area = height[x] * (x - y)
                    x -= 1
                MAX = max(MAX, area)
            return MAX
            

    思路是从数组两端开始,比较当前最大容积,然后看哪块“木板”低,就往中间进一格找下一块“木板”代替。比起我的方法,省去了很多不必要的比较。

    给出一个整数,把它转换为罗马数字(注意特殊规则)。思路是把整数和罗马数字、以及特殊整数和罗马数字一一对应起来,建立两个数组,然后对input从

    大到小地去进行除法和取余,除数用罗马数字进行转换,余数作为新input再进行转换操作。贴上代码:

    class Solution(object):
        def intToRoman(self, num):
            """
            :type num: int
            :rtype: str
            """
            values = [ 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 ]
            numerals = [ "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" ]
            res, i = "", 0
            while num:
                res += (num/values[i]) * numerals[i]
                num %= values[i]
                i += 1
            return res

    上一题的反向过程,只需注意是否有罗马数字前置的特殊情况即可,遍历罗马数字字符串,一个一个的解析然后累加即可。贴上代码:

    class Solution(object):
        def romanToInt(self, s):
            """
            :type s: str
            :rtype: int
            """
            map = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
            num, pre = 0, 1000
            for i in [map[j] for j in s]:
                num, pre = num + i - 2 * pre if i > pre else num + i, i
            return num

    寻找数组里面所有字符串的最长公共前缀。思路是对所有字符串两个一组找出公共前缀,然后组成一个新的数组,再对这个新数组进行同样的操作,直到数组长度为1。(当数组长度是奇数的时候,在数组尾部再补上一个strs[-1])

    class Solution(object):
        def longestCommonPrefix(self, strs):
            """
            :type strs: List[str]
            :rtype: str
            """
            if len(strs) <= 0: return ''
            if len(strs) == 1: return strs[0]
            if len(strs) % 2 == 1: strs.append(strs[-1])
            strs1 = strs[0::2]
            strs2 = strs[1::2]
            newStrs = [self.findCommonPrefix(strs1[i], strs2[i]) for i in xrange(len(strs1))]
            return self.longestCommonPrefix(newStrs)
        
        def findCommonPrefix(self, str1, str2):
            if len(str1) < len(str2):
                temp = str1
                str1 = str2
                str2 = temp
            currIndex = totalLength = len(str2)
            if str2 == str1[0:currIndex]: return str2
            while(1):
                if str2[0:currIndex] == str1[0:currIndex]:
                    if str2[0:currIndex + 1] == str1[0:currIndex + 1]:
                        currIndex = (totalLength + currIndex) / 2
                    else:
                        return str2[0:currIndex]
                else:
                    if str2[0:currIndex - 1] == str1[0:currIndex - 1]:
                        return str2[0:currIndex - 1]
                    else:
                        currIndex /= 2
                if currIndex == 0:
                    return ''
            

     给出一个整数数组,找出里面能相加为零的三个数的所有组合。我的方法最后一个test case超时,和暴搜其实没啥区别,就是找第三个数的时候用了一下二分。贴上我的代码:

    class Solution(object):
        def threeSum(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            totalLength = len(nums)
            if totalLength < 3: return []
            nums = sorted(nums)
            p, q = 0, 1
            ret = []
            while (p <= totalLength - 3):
                if nums[p] > 0:
                    break
                numRequired = 0 - nums[p] - nums[q]
                index = totalLength - 1
                range1, range2 = q, totalLength - 1
                while(index > range1 and index <= range2):
                    if nums[index] < numRequired:
                        range1 = index
                        index = (range2 + index) / 2
                    elif nums[index] == numRequired:
                        ret.append([nums[p], nums[q], numRequired])
                        break
                    else:
                        range2 = index
                        index = (range1 + index) / 2
                q += 1
                while(nums[q] == nums[q - 1] and q < totalLength - 1):
                    q+=1
                if q == totalLength - 1:
                    p += 1
                    while(nums[p] == nums[p-1]):
                        p += 1
                        if p > totalLength - 3:
                            return ret
                    q = p + 1
            return ret

    看了一下别人的思路,和我的区别在于:同样是三个指针p、q、r,我的方法是固定p、q然后通过二分移动r去找第三个数,没找到后再移动q;他的方法是固定p,移动q、r,三个数的和大于零则把r往左移,小于零则把q往右移。这样在同等的p、q、r下,就比我的少了很多寻找步骤。

    贴上代码:

    class Solution(object):
        def threeSum(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            res = []
            nums = sorted(nums)
            length = len(nums)
            for i in xrange(length - 2):
                if nums[i] > 0: break
                if i > 0 and nums[i] == nums[i - 1]: continue
                l, r = i + 1, length - 1
                while l < r:
                    total = nums[i] + nums[l] + nums[r]
    
                    if total < 0:
                        l += 1
                    elif total > 0:
                        r -= 1
                    else:
                        res.append([nums[i], nums[l], nums[r]])
                        while l < r and nums[l] == nums[l + 1]:
                            l += 1
                        while l < r and nums[r] == nums[r - 1]:
                            r -= 1
                        l += 1
                        r -= 1
            return res
  • 相关阅读:
    HanTTS简单文档
    一张包含所有颜色的图片
    shiro整合SpringMVC基于xml
    设计模式-享元模式
    关于volatile关键字实现的个人理解
    重量级锁
    轻量级锁
    偏向锁
    Seata概念的总结
    苹果手机怎么把资源库的APP放到桌面
  • 原文地址:https://www.cnblogs.com/HorribleMe/p/12594504.html
Copyright © 2020-2023  润新知