【DW组队学习—LeetCode】day03

11. 盛最多水的容器

给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器。
【示例1】输入:[1,8,6,2,5,4,8,3,7] 输出:49
解释:图中垂直线代表输入数组[1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
【示例2】输入:height = [1,1] 输出:1
【示例3】输入:height = [4,3,2,1,4] 输出:16
【示例4】输入:height = [1,2,1] 输出:2
提示:

  • n = height.length
  • 2 <= n <= 3 * 104
  • 0 <= height[i] <= 3 * 104

尝试思路:
遍历两个垂线之间的体积,同时记录当前出现的最大体积

代码:

class Solution:
    def maxArea(self, height: List[int]) -> int:
        v_max, v = 0, 0
        l = len(height)
        for i in range(l):
            for j in range(i+1,l):
                v = min(height[i],height[j]) * (j-i)
                v_max = max(v, v_max)
        return v_max

错误:运行超时
原因:遍历复杂度过高,耗费时间太长
【DW组队学习—LeetCode】day03_第1张图片
暂时没想到别的方法

14. 最长公共前缀

题目要求

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
【示例 1】输入:strs = [“flower”,“flow”,“flight”] 输出:“fl”
【示例 2】输入:strs = [“dog”,“racecar”,“car”] 输出:""
解释:输入不存在公共前缀。
提示:

  • 0 <= strs.length <= 200
  • 0 <= strs[i].length <= 200
  • strs[i] 仅由小写英文字母组成

尝试思路1:
1、找到长度最短的元素,将其字符作为对比字符(得到列表中所有元素的长度列表,使用list.index(min)函数得到其索引,对应找到长度最短元素)
2、依次对比每个元素的每一位字符(以长度最短元素的字符作为对比字符)
2.1 如果与对比字符不同,则结束循环
2.2 如果均与对比字符相同,则计入公共序列
3、输出结果

测试中出现的未考虑到的案例:原始元素列表为空列表[]

代码:

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        ps = "" #最长公共前缀
        if strs:
            list_l = [len(i) for i in strs] #记录列表元素长度
            s = strs[list_l.index(min(list_l))] #字符最少元素
            for i in range(len(s)):
                same = 0 #相同标识符,=0表示有不相同字符,=1表示相同
                for j in range(len(strs)):
                    if strs[j][i] == s[i]:
                        same = 1
                    else:
                        same = 0
                        break
                if same == 1:
                    ps = ps + s[i]
                else:
                    break
        return ps

【DW组队学习—LeetCode】day03_第2张图片
尝试思路2:
1、找到元素中最短元素的长度(步骤同上)
2、依次取每个元素的第i位组成集合(不包含重复元素),若集合长度为1,则所有元素的第i位相同,否则结束循环
3、输出结果

代码:

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        ps = "" #最长公共前缀
        if strs:
            list_l = [len(i) for i in strs] #记录列表元素长度
            s = strs[list_l.index(min(list_l))] #字符最少元素
            for i in range(len(s)):
                set_c = set([strs[j][i] for j in range(len(strs))])
                if len(set_c) == 1:
                    ps = ps + s[i]
                else:
                    break
        return ps

【DW组队学习—LeetCode】day03_第3张图片
方法2耗时明显减少,但是内存一直不低

15. 三数之和

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
【示例 1】输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]]
【示例 2】输入:nums = [] 输出:[]
【示例 3】输入:nums = [0] 输出:[]
提示:

  • 0 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

尝试思路1:
1、判断nums里的元素个数,小于3直接输出空列表,否则继续步骤2
2、对nums进行排序(使用sort方法,没有返回值,直接修改原列表),三层循环,判断是否已经在现有列表里存在,若已存在则不再存入
3、输出结果

代码:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        result = []
        if len(nums) >= 3:
            nums.sort()
            for i in range(len(nums)):
                for j in range(i+1, len(nums)):
                    for t in range(j+1, len(nums)):
                        if (nums[i] + nums[j] + nums[t] == 0) and [nums[i], nums[j], nums[t]] not in result:
                                result.append([nums[i], nums[j], nums[t]])
        return result


【DW组队学习—LeetCode】day03_第4张图片
根据提交结果可知,在时间限制内,没有出错,但是复杂度还是很高,导致时间过长

尝试思路2:
1、判断nums里的元素个数,小于3直接输出空列表,否则继续步骤2
2、对nums进行排序,并使用pop方法在nums列表中依次取出两个数(a从原序列取,b从去a序列取,c从去ab序列取),然后计算需要的第三个数是什么,并判断是否在剩下列表中存在第三个数,若不存在则不计入,若存在判断是否已经有了该组合,若有了也不计入
3、输出结果

代码:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        result = []
        a, b, c = 0, 0, 0
        if len(nums) >= 3:
            nums.sort()
            for i in range(len(nums)):
                anums = nums
                a = anums.pop(i)
                for j in range(len(anums)):
                    bnums = anums
                    b = bnums.pop(j)
                    c = 0 - a - b
                    r = [a, b, c]
                    r.sort()
                    if (c in bnums) and (r not in result):
                        result.append(r) 
        return result

错误:索引超过范围
原因:“假赋值”,当删除中间商的某个元素时,一条等式链上的列表都会更新
【DW组队学习—LeetCode】day03_第5张图片
解决方法:用copy.deepcopy(list)代替原赋值,解决了该错误,但仍存在运行超时问题

同时,采取remove方法取代pop方法
代码:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        result = []
        a, b, c = 0, 0, 0
        if len(nums) >= 3:
            nums.sort()
            anums = copy.deepcopy(nums)
            for a in anums:
                anums.remove(a)
                bnums = copy.deepcopy(anums)
                for b in bnums:
                    bnums.remove(b)
                    c = 0 - a - b
                    r = [a, b, c]
                    r.sort()
                    if (c in bnums) and (r not in result):
                        result.append(r) 
        return result

错误:少了一组答案
原因:没有理解for循环取值的原理,以为更新后会从头开始,实际上for循环按照索引进行取值,被循环列表更新后,仍是原来的索引,即原来索引为1的值在更新后索引变成了0,但for仍取新列表中索引为1的值,故而一些数据被跳过,导致答案缺失。所以应该一直用原序列做循环。
【DW组队学习—LeetCode】day03_第6张图片
更改后代码:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        result = []
        a, b, c = 0, 0, 0
        if len(nums) >= 3:
            nums.sort()
            anums = copy.deepcopy(nums)
            for a in nums:
                anums.remove(a)
                bnums = copy.deepcopy(anums)
                for b in anums:
                    bnums.remove(b)
                    c = 0 - a - b
                    r = [a, b, c]
                    r.sort()
                    if (c in bnums) and (r not in result):
                        result.append(r) 
        return result

但仍超时,悲剧

你可能感兴趣的:(DW组队学习,LeetCode,Python,leetcode)