Divide and Conquer

本文介绍了解决天际线问题的算法,利用最大堆实现建筑物轮廓的描绘,并提出了不同方式添加括号计算表达式的解决方案,通过递归枚举所有可能的计算顺序。

1

2 218 The Skyline Problem     最大堆   遍历节点

    public List<int[]> getSkyline(int[][] buildings) {
        List<int[]> res = new ArrayList<>();
        List<int[]> point = new ArrayList<>();
        for (int i = 0; i < buildings.length; i++)
        {
            point.add(new int[]{buildings[i][0], buildings[i][2]});
            point.add(new int[]{buildings[i][1], -buildings[i][2]});
        }
        Collections.sort(point, (a,b)-> {
            if (a[0] != b[0]) return a[0] - b[0];
            return b[1] - a[1];});
        PriorityQueue<Integer> maxheap = new PriorityQueue<>((a,b)->(b - a));
        int cur = 0, pre = 0;
        for (int i = 0; i < point.size(); i++)
        {
            int[] b = point.get(i);
            if (b[1] > 0)
            {
                maxheap.add(b[1]);
                cur = maxheap.peek();
            }
            else
            {
                maxheap.remove(-b[1]);
                cur = maxheap.peek() == null ? 0 : maxheap.peek();
            }
            if (pre != cur)
            {
                res.add(new int[]{b[0], cur});
                pre = cur;
            }
        }
        return res;
    }
View Code

 3  241 Different Ways to Add Parentheses   找符号,分开

    public List<Integer> diffWaysToCompute(String input) {
        List<Integer> res = new LinkedList<>();
        for (int i = 0; i < input.length(); i++)
        {
            char c = input.charAt(i);
            if (c == '+' || c == '-' || c == '*')
            {
                String a = input.substring(0, i);
                String b = input.substring(i+1);
                List<Integer> a1 = diffWaysToCompute(a);
                List<Integer> b1 = diffWaysToCompute(b);
                for (int x : a1)
                {
                    for (int y : b1)
                    {
                        if (c == '+')
                        {
                            res.add(x + y);
                        }
                        else if (c == '-')
                        {
                            res.add(x - y);
                        }
                        else if (c == '*')
                        {
                            res.add(x * y);
                        }
                    }
                }
            }
        }
        if (res.size() == 0) res.add(Integer.valueOf(input));
        return res;
    }
View Code

 

转载于:https://www.cnblogs.com/whesuanfa/p/6817014.html

### 分治算法的时间复杂度 分治算法是一种重要的算法设计技术,其核心在于将一个问题分解成多个较小规模的相同问题,分别求解后再合并各个子问题的结果得到原始问题的答案。对于这类算法而言,时间复杂度主要取决于三个因素: - **分解操作的成本**:即将原问题划分为更小子问题所需的工作量。 - **解决各子问题所需的总成本**:这通常是递归调用本身的时间开销。 - **组合子问题解决方案的成本**:即如何有效地把所有子问题的解答汇总起来形成最终答案。 #### 计算方法 为了计算分治算法的时间复杂度,可以利用主定理(Master Theorem),它提供了一种简便的方法来估计形如 \(T(n)=aT(\frac{n}{b})+f(n)\) 的递推关系式的渐近界[^3]。这里, - \(n\) 表示输入大小; - \(a \geq 1\) \(b > 1\) 是常数; - \(f(n)\) 描述了除递归外其他部分工作量的增长速度。 当应用到具体的例子时,比如快速排序,如果每次都能均匀分割,则有 \(a=2\),\(b=2\),而额外处理(比较交换元素)大致线性增长,因此 \(f(n)=O(n)\),从而得出平均情况下快速排序的时间复杂度为 \(O(n\log n)\)[^4]。 #### 示例 考虑经典的归并排序作为实例展示分治算法及其时间复杂度分析过程: ```java public class MergeSort { public static void merge(int[] array, int left, int mid, int right){ // 合并两个已排序序列... } public static void sort(int[] array, int left, int right){ if (left < right){ int mid = (left + right)/2; // 对左半边进行递归排序 sort(array, left, mid); // 对右半边进行递归排序 sort(array, mid+1, right); // 将两部分有序数组合并在一起 merge(array, left, mid, right); } } } ``` 在这个实现中,`sort()` 函数负责递归地拆分子数组直到不能再分为止,之后再由 `merge()` 来完成实际的数据整理任务。由于每层递归都会使待处理区间减半,并且每一层都需要遍历整个列表来进行合并操作,故此算法的整体时间复杂度同样遵循 \(O(n\log n)\) 的规律。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值