DW&LeetCode_day3(11、14、15)
写在前面:
- 开始第三天的内容啦!各位小伙伴加油哦!
开源内容
学习大纲
目录
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
链接:题目链接题解:
# python # x和y的值要趋向最大 # 设置两个变量一个指向第一个一个指向最后一个 # 让x趋向最大,保留两个height中的较大值使y趋向最大,另一个值向中间移动。 maxn = 0 i = 0 j = len(height)-1 while(i < j): if(height[i] < height[j]): maxn = max(maxn,height[i]*(j-i)) i += 1 else: maxn = max(maxn,height[j]*(j-i)) j -= 1 return maxn
//Scala 指针探索法 def maxArea(height: Array[Int]): Int = { var i = 0 var j = height.length-1 var maxarea = 0 while (i<j){ maxarea = math.max(maxarea,math.min(height(i),height(j))*(j-i)) if(height(i)<height(j)) i+=1 else j-=1 } return maxarea }
// JavaScript let x, y = 0, i = 0, l = height.length - 1; while (i < l) if ((x = (l - i) * (height[i] > height[l] ? height[l--] : height[i++])) > y) y = x; return y;
14. 最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:
输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。
提示:
0 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] 仅由小写英文字母组成
链接:题目链接题解:
// Scala // 纵向看最长前缀就是每一列均有元素切均为同一元素。 // 1.仅需要获取最短范围[为保证转制可正常] // 2.转制矩阵,列变行 // 3.获取每一行均为同一元素的 // 4.输出 object Solution { def longestCommonPrefix(strs: Array[String]): String = { strs match{ case a if a.length==0 =>"" case otherwise=> val minLength=strs.map(_.length).min strs.map(_.split("").take(minLength)) .transpose .takeWhile(n=>n.distinct.length==1) .map(_.head) .mkString("") } }
# python return strs[0][:([len(set(ch))==1 for ch in zip(*strs)] + [False]).index(False)] if strs else ''
# python ans = '' for i in zip(*strs): #首先通过星号的这一步操作将strs解包,使其中的每个字符串变成独立的参数,比如:["flower","flow","flight"],就变成了"flower","flow","flight",然后zip函数在将纵向排列 if len(set(i)) == 1: #如果将zip纵向排列后的对象里的字母进行删除重复后(set函数),该对象的长度变为了1,那么表明在所有的字符中的对应位置都是这个字母 ans += i[0] else: #当首次出现一个不是删重后长度不是1的,即为首次出现了不同字母,结束公共前缀的查找 break return ans
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
链接:题目链接题解:
import scala.collection.mutable.ListBuffer import scala.util.control.Breaks._ object Solution { /** * "排序+双指针" */ def threeSum(nums: Array[Int]): List[List[Int]] = { val result = ListBuffer[List[Int]]() val nums_size = nums.size if(nums_size > 2){ val snums = nums.sortWith(_<_) breakable{ for(i <- 0 until nums_size){ //因为排序了,如果snums(i)>0,则后面的相加都不会等于0 if(snums(i) > 0){ break() } if(i == 0 || (snums(i-1) != snums(i))){ //i + j +k = 0 //j+k = -i //转化成求两个数之和 val target:Int = -snums(i) var j = i+1 var k = nums_size - 1 while(j < k){ if( snums(j) + snums(k) == target){ result += List[Int](snums(i),snums(j),snums(k)) j += 1 k -= 1 while( j < k && snums(j)==snums(j-1)){j += 1} while( j < k && snums(k)==snums(k+1)){k -= 1} }else if( snums(j) + snums(k) > target){ //大于target,right应该向左移动 k += -1 }else if(snums(j) + snums(k) < target){ //小于target,left应该向右移动 j += 1 }else{ } } } } } } result.toList } }
class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: res=[] nums.sort() for i in range(len(nums)): if len(nums)<3: return [] #当遍历到大于的元素时就退出循环,因为要遍历的元素相加不可能再为0 if nums[i]>0: break #遇到相邻元素相等,就跳过这一层的循环开始下一层循环 if i>=1 and nums[i]==nums[i-1]: continue #TODO 这里寻找target的时候使用set() target=-nums[i] cache=set() for j in range(i+1,len(nums)): num1=target-nums[j] if num1 in cache: if len(res)==0 or res[-1]!=[nums[i],num1,nums[j]]: res.append([nums[i],num1,nums[j]]) cache.add(nums[j]) return res
# 可读性不高,不建议使用 class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: d = collections.Counter(nums) return [[i, j, -i-j] for i in [m for m in d if m <= 0] for j in d if (-i - j) >= j >= i and (-i-j) in d and collections.Counter([i, j, -i - j]).get(i) <= d.get(i) and collections.Counter([i, j, -i - j]).get(j) <= d.get(j)]