【LeetCode】Sama的个人记录_71

在这里插入图片描述

优雅的字符串动态规划。
class Solution {
    public int minDistance(String word1, String word2) {
        int len1 = word1.length();
        int len2 = word2.length();
        // dp[i][j]的含义是,word1和word2转化为相同需要的删除操作次数
        int[][] dp = new int[len1 + 1][len2 + 1];
        // 初始化
        for (int i = 1; i <= len1; i++) {
            dp[i][0] = i;
        }
        for (int j = 1; j <= len2; j++) {
            dp[0][j] = j;
        }
        // 状态转移
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + 1;
                }
            }
        }
        return dp[len1][len2];
    }
}

 
 

在这里插入图片描述

两个矩形的位置关系多种多样,很难分类讨论。下面是最优雅的解法。
class Solution {
    public int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
        int s1 = (ax2 - ax1) * (ay2 - ay1);
        int s2 = (bx2 - bx1) * (by2 - by1);
        int w = Math.min(ax2, bx2) - Math.max(ax1, bx1);
        int h = Math.min(ay2, by2) - Math.max(ay1, by1);
        int s3 = Math.max(w, 0) * Math.max(h, 0);
        return s1 + s2 - s3;
    }
}

 
 

在这里插入图片描述

这是一个数据流形式的扩展区间/合并区间问题。看似复杂,其实只有5种情况。

假设当前数字为val,[l0, r0]为其左侧区间,[l1, r1]为其右侧区间:
情况一:"l0 <= val <= r0"。val包含在区间内部,无需进行任何操作。
情况二:"r0 + 1 = val"。左侧区间向右扩展一小步。
情况三:"l1 - 1 = val"。右侧区间向左扩展一小步。
情况四:同时满足情况二和情况三,区间发生合并。
情况五:上述情况都不满足,则独立形成一个新的区间。

技巧>_<TreeMap<Integer, Integer>数据结构来表示众多区间。
一来自带排序,二来可以使用floorEntry()ceilingEntry()方法轻易获取左右区间。
class SummaryRanges {

    private TreeMap<Integer, Integer> intervals;

    public SummaryRanges() {
        intervals = new TreeMap<>();
    }

    public void addNum(int val) {
        // 左侧区间/右侧区间
        Map.Entry<Integer, Integer> interval0 = intervals.floorEntry(val);
        Map.Entry<Integer, Integer> interval1 = intervals.ceilingEntry(val + 1);
        // 区间边界
        // int l0 = interval0.getKey(), r0 = interval0.getValue();
        // int l1 = interval1.getKey(), r1 = interval1.getValue();
        // 分情况讨论
        if (interval0 != null && interval0.getKey() <= val && val <= interval0.getValue()) {
            // 情况一(val包含在区间内部,无需进行任何操作)
            return;
        } else {
            boolean extendL = interval0 != null && interval0.getValue() + 1 == val;
            boolean extendR = interval1 != null && interval1.getKey() - 1 == val;
            if (extendL && extendR) {
                // 情况四(同时满足情况二和情况三,区间发生合并)
                int l = interval0.getKey();
                int r = interval1.getValue();
                intervals.remove(interval0.getKey());
                intervals.remove(interval1.getKey());
                intervals.put(l, r);
            } else if (extendL) {
                // 情况二(左侧区间向右扩展一小步)
                intervals.put(interval0.getKey(), interval0.getValue() + 1);
            } else if (extendR) {
                // 情况三(右侧区间向左扩展一小步)
                int k = interval1.getKey();
                int v = interval1.getValue();
                intervals.remove(k);
                intervals.put(k - 1, v);
            } else {
                // 情况五(上述情况都不满足,则独立形成一个新的区间)
                intervals.put(val, val);
            }
        }
    }

    public int[][] getIntervals() {
        // 将TreeMap数据结构转化为int[][]数据结构
        int len = intervals.size();
        int idx = 0;
        int[][] res = new int[len][2];
        for (Map.Entry<Integer, Integer> interval : intervals.entrySet()) {
            res[idx][0] = interval.getKey();
            res[idx][1] = interval.getValue();
            idx++;
        }
        return res;
    }
}

 
 
 
 
 
 
 
 
 
 
 
 
 
 

检索标记:352. 将数据流变为多个不相交区间给你一个由非负整数 a1, a2, …, an 组成的数据流输入,请你将到目前为止看到的数字总结为不相交的区间列表。实现 SummaryRanges 类SummaryRanges() 使用一个空数据流初始化对象。void addNum(int val) 向数据流中加入整数 val 。int[][] getIntervals() 以不相交区间 [starti, endi] 的列表形式返回对数据流中整数的总结。223. 矩形面积给你 二维 平面上两个 由直线构成的 矩形,请你计算并返回两个矩形覆盖的总面积。每个矩形由其 左下 顶点和 右上 顶点坐标表示:第一个矩形由其左下顶点 (ax1, ay1) 和右上顶点 (ax2, ay2) 定义。第二个矩形由其左下顶点 (bx1, by1) 和右上顶点 (bx2, by2) 定义。583. 两个字符串的删除操作给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。示例:输入: “sea”, “eat"输出: 2解释: 第一步将"sea"变为"ea”,第二步将"eat"变为"ea"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值