Leetcode Task03: 完成以下三个题目并打卡(1天)

Task03: 完成以下三个题目并打卡(1天)

 

011 盛最多水的容器

给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

解题思路
首先,这道题中所有的直线都是垂直于X轴的,n个正整数代表的是桶的高度,两个正整数代表的直线和X轴围成一个桶,盛水的多少和桶的最短边和桶的底部所决定。

双指针的方法,分别指向列表的两端,逐步向中间逼近,最后返回最大值。而逼近的方法是较高的那头不动,较低的那头向高的那头移动。

//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public int maxArea(int[] height) {
        int area = 0, left = 0, right = height.length - 1;
        while (left < right) {
            area = Math.max(area, Math.min(height[left], height[right])*(right-left));
            if(height[left]<height[right])
                left++;
            else
                right--;
        }
        return area;
    }
}
//leetcode submit region end(Prohibit modification and deletion)

014 最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。

示例 1:
输入:strs = ["flower","flow","flight"]
输出:"fl"

示例 2:
输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。

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

解题思路

利用递归分治法实现

我们设置一个递归函数,求数组中从索引left到索引right之间的字符串的最长公共前缀。

递归终止条件:当索引left == 索引right时,此时只有一个字符串,直接返回该字符串。

递归过程:先求出从索引left到索引mid左半边的最长公共前缀,再求出索引mid + 1到索引right右半边的最长公共前缀。再取这两个最长公共前缀的最长公共前缀返回即可。

时间复杂度是O(n * log(m)),其中n为最长公共前缀的长度,m为字符串数组的长度。对于空间复杂度是O(log(m))级别的,因为我们使用了递归分治算法,递归深度就是递归的空间复杂度。

//leetcode submit region begin(Prohibit modification and deletion)
public class Solution {

    public String longestCommonPrefix(String[] strs) {
        if(strs.length == 0) {
            return "";
        }
        return longestCommonPrefix(strs, 0, strs.length - 1);
    }

    private String longestCommonPrefix(String[] strs, int left, int right) {
        if(left == right) {
            return strs[left];
        }
        int mid = left + (right - left) / 2;
        String leftResult = longestCommonPrefix(strs, left, mid);
        String rightResult = longestCommonPrefix(strs, mid + 1, right);
        int i = 0;
        for(; i < leftResult.length(); i++) {
            if(rightResult.length() <= i || rightResult.charAt(i) != leftResult.charAt(i)) {
                break;
            }
        }
        return leftResult.substring(0, i);
    }
}
//leetcode submit region end(Prohibit modification and deletion)

015 三数之和

给你一个包含 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

//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        int len = nums.length;
        // 从小到大排序
        Arrays.sort(nums);
        for (int i = 0; i < len && nums[i]<=0; i++) {
            // target的值不可以重复
            if (i>0 && nums[i] == nums[i-1]) {
                continue;
            }
            int left = i+1;
            int right = len - 1;
            int target = -1*nums[i];
            while (left<right) {
                if (nums[left]+nums[right]==target) {
                    result.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    // 因为只有两个数字,只要一个数字重复,另一个数字也必然重复,就有可能出现重复解
                    while (left<right && nums[left]==nums[left+1]) {
                        left++;
                    }
                    while (left<right && nums[right]==nums[right-1]) {
                        right--;
                    }
                    left++;
                    right--;
                }else if(nums[left]+nums[right]<target){
                    left++;
                }else{
                    right--;
                }
            }
        }

        return result;
    }
}
//leetcode submit region end(Prohibit modification and deletion)
posted @ 2021-01-13 15:11  Vincy_Lemon  阅读(91)  评论(0)    收藏  举报