【算法】算法题三道汇总区间,接雨水,路径交叉

70 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15 天

大家好,我是小冷。 今天还是继续学习算法技术知识吧

汇总区间

给定一个无重复元素的有序整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x 。 列表中的每个区间范围 [a,b] 应该按如下格式输出:

"a->b" ,如果 a != b "a" ,如果 a == b

示例 1:

输入:nums = [0,1,2,4,5,7] 输出:["0->2","4->5","7"] 解释:区间范围是: [0,2] --> "0->2" [4,5] --> "4->5" [7,7] --> "7"

示例 2:

输入:nums = [0,2,3,4,6,8,9] 输出:["0","2->4","6","8->9"] 解释:区间范围是: [0,0] --> "0" [2,4] --> "2->4" [6,6] --> "6" [8,9] --> "8->9"

示例 3:

输入:nums = [] 输出:[]

示例 4:

输入:nums = [-1] 输出:["-1"]

示例 5:

输入:nums = [0] 输出:["0"]

提示:

0 <= nums.length <= 20 -231 <= nums[i] <= 231 - 1 nums 中的所有值都 互不相同 nums 按升序排列

JAVA 解答参考

class Solution {
    public List<String> summaryRanges(int[] nums) {
        List<String> list = new ArrayList<>();
        int pre = 0;
        int next = 0;
        for (int i = 0; i < nums.length; i++) {
            if (i + 1 < nums.length && nums[i + 1] - nums[i] == 1) {
                next = i + 1;
            } else {
                if (next < i)
                    next = i;
                if (pre != next) {
                    list.add(nums[pre] + "->" + nums[next]);
                    pre = i + 1;
                }
                if (pre == next) {
                    list.add(nums[pre] + "");
                    pre = i + 1;
                }
            }
        }
        return list;
    }
}

接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

示例 1:

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

示例 2:

输入:height = [4,2,0,3,2,5] 输出:9

提示:

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

以下程序实现了这一功能,请你填补空白处内容:

java解答参考

	class Solution {
		public int trap(int[] height) {
			if (height == null)
				return 0;
			int len = height.length;
			if (len == 0)
				return 0;
			int res = 0;
			int[] left_max = new int[len];
			int[] right_max = new int[len];
			left_max[0] = height[0];
	
			for (int i = 1; i < len; i++) {
				left_max[i] = Math.max(height[i], left_max[i - 1]);
			}
			right_max[len - 1] = height[len - 1];
	
					答案在下面
			__________________;
	
			for (int i = 1; i < len - 1; i++) {
				res += Math.min(left_max[i], right_max[i]) - height[i];
			}
			return res;
		}
	}
for (int i = len - 2; i >= 0; i--) {
      right_max[i] = Math.max(height[i], right_max[i + 1]);
}

路径交叉

给你一个整数数组 distance 。

从 X-Y 平面上的点 (0,0) 开始,先向北移动 distance[0] 米,然后向西移动 distance[1] 米,向南移动 distance[2] 米,向东移动 distance[3] 米,持续移动。也就是说,每次移动后你的方位会发生逆时针变化。

判断你所经过的路径是否相交。如果相交,返回 true ;否则,返回 false 。

示例 1: 在这里插入图片描述

输入:distance = [2,1,1,2] 输出:true

示例 2:

输入:distance = [1,2,3,4] 输出:false

示例 3:

输入:distance = [1,1,1,1] 输出:true

提示:

1 <= distance.length <= 105 1 <= distance[i] <= 105

java解答参考

class Solution {
    public boolean isSelfCrossing(int[] x) {
        if (x.length < 4)
            return false;
        int a = 0, b = 0, c = 0;
        int d = x[0], e = x[1], f = x[2];
        for (int i = 3; i < x.length; i++) {
            a = b;
            b = c;
            c = d;
            d = e;
            e = f;
            f = x[i];
            if (e < c - a && f >= d)
                return true;
            if (c - a <= e && e <= c && f >= (d - b < 0 ? d : d - b))
                return true;
        }
        return false;
    }
}