DW&LeetCode_day3(11、14、15)

DW&LeetCode_day3(11、14、15)


写在前面:

  • 开始第三天的内容啦!各位小伙伴加油哦!

开源内容

开源内容

学习大纲 


目录

DW&LeetCode_day3(11、14、15)

写在前面:

开源内容

学习大纲

 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


链接:题目链接

Video_2019-06-19_192352.gif

题解:

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)]


猜你喜欢

转载自blog.csdn.net/adminkeys/article/details/112560527