LeetCode热题100道-Day03

451 阅读1分钟

LeetCode热题100道-Day03

11. 盛最多水的容器

  • 使用双指针解题,这道题求盛水最多就是求两数乘积最大。求面积最大,左指针在头,右指针在尾,对数组遍历,求对面积记录,通过函数取它们的最大值。同时在遍历时,面积宽度在缩小,移动的是两端高度较低的一侧,最后返回最大面积max。
class Solution {
    public int maxArea(int[] height) {
        int left = 0, right = height.length - 1;
        int max = 0;

        while (left < right) {

            int ans = (right - left) * Math.min(height[left], height[right]);
            max = Math.max(ans, max);
            if (height[left] < height[right]) ++left;
            else --right;
        }
        return max;
    }
}

15. 三数之和

  • 使用双指针解题,首先对数组进行排序,对特例进行排除,对第一个数进行去重,i从下标0的地方开始,同时定一个下标 left 定义在i+1的位置上,定义下标 right 在数组结尾的位置上,sum = nums[i] + nums[left] + nums[right] ,再对第二个数num[left]和第三个数nums[right]去重,找到结果后,left和right收缩。
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);
        int len = nums.length;
        //nums中数全为正或者负
        if (nums[0] > 0 || nums[len - 1] < 0) return result;

        for (int i = 0; i < len; i++) {
            //排序后第一个大于0,之后的数都大于0,得不到三数之和为0
            if (nums[i] > 0) {
                return result;
            }
            //去掉重复数
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            int left = i + 1;
            int right = len - 1;
            while (left < right) {
                int sum = nums[i] + nums[left] + nums[right];
                //sum小于0, left右移,sum才能变大
                if (sum < 0) {
                    ++left;
                //sum大于0,right左移,sum才能变小
                } else if (sum > 0) {
                    --right;
                } else {
                    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--;
                }
            }
        }
        return result;
    }
}

17. 电话号码的字母组合

  • 使用回溯算法解决。
class Solution {
    //全局列表result,来存储组合
    List<String> result = new ArrayList<>();
    //使用StringBuilder进行拼接
    StringBuilder temp = new StringBuilder();

    public List<String> letterCombinations(String digits) {
        //digits长度为0情况
        if (digits.length() == 0) {
            return result;
        }
        //一个映射表,初始对应所有的数字,为了直接对应2-9,新增了两个无效的字符串""
        String[] letterMap = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
        //进行迭代
        backTracking(digits, letterMap, 0);
        return result;
    }
    //index:为digits的下标
    public void backTracking(String digits, String[] letterMap, int index) {
        //递归的终止条件,并记录得到的字符串
        if (index == digits.length()) {
            result.add(temp.toString());
            return;
        }
        //digits.charAt(index) - '0':得到再letterMap中的下标,从而得到所对应的字符串
        String str = letterMap[digits.charAt(index) - '0'];
        for (int i = 0; i < str.length(); i++) {
            temp.append(str.charAt(i));
            //递归,对下一个数
            backTracking(digits, letterMap, index + 1);
            //删除加上的字符,回溯
            temp.deleteCharAt(temp.length() - 1);
        }
    }
}