美文网首页线段树
Java 算法 - 约翰的生意(线段树)

Java 算法 - 约翰的生意(线段树)

作者: 琼珶和予 | 来源:发表于2018-03-05 22:59 被阅读0次

题意

在一条数轴上,有n个城市,编号从0 ~ n – 1 , 约翰打算在这n个城市做点生意,他对Armani的一批货物感兴
趣,每个城市对于这批货物都有一个价格prices[i]。对于城市x,约翰可从城市编号为[x - k, x + k]购买货物,然后
卖到城市x,问约翰在每个城市最多能赚到多少钱?

样例

给出 prices = [1, 3, 2, 1, 5], k = 2,返回 [0, 2, 1, 0, 4]。
解释:
i = 0,约翰可去的城市有0~2因为1、2号城市的价格比0号城市的价格高,所以赚不了钱,即 ans[0] = 0。
i = 1,可去的城市有0~3,可以从0号或者3号城市购买货物赚取的差价最大,即ans[1] = 2。
i = 2,可去的城市有0~4,显然从3号城市购买货物赚取的差价最大,即ans[2] = 1。
i = 3,可去的城市有1~4,没有其他城市的价格比3号城市价格低,所以赚不了钱,ans[3] = 0。
i = 4,可去的城市有2~4,从3号城市购买货物赚取的差价最大,即ans[4] = 4。

给出 prices = [1, 1, 1, 1, 1], k = 1, 返回 [0, 0, 0, 0, 0]。
解释:
所有城市价格都一样,所以不能赚到钱,即所有的ans都为0。

1.解题思路

  这是一道非常典型的线段树题。之前我也做过类似的题,Java 算法-区间求和I(线段树),其实原理都是差不多的。重点在于构建线段树,这里构造的线段树,用来记录每个区域的最小值。在最大的差价是,我只要在这个范围找到最小值,然后求最小值就行了。

2.代码

 public int[] business(int[] A, int k) {
        SegmentTreeNode node = build(A, 0, A.length - 1);

        int a[] =  new int[A.length];
        for(int i = 0; i < a.length; i++){
            SegmentTreeNode n = node;
            int min = Math.max( i -k, 0);
            int max = Math.min(i + k, A.length - 1);
            a[i] = Math.max( A[i]  - query(node, min, max), 0);
        }
        return a;
    }


    class SegmentTreeNode {
        public int start = 0;
        public int end = 0;
        public int min = 0;
        public SegmentTreeNode left = null;
        public SegmentTreeNode right = null;

        public SegmentTreeNode(int start, int end, int min) {
            this.start = start;
            this.end = end;
            this.min = min;
        }

    }
    //构建线段树
    private SegmentTreeNode build(int A[], int start, int end) {
        SegmentTreeNode node = new SegmentTreeNode(start, end, A[0]);
        if (node.start == node.end) {
            node.min = A[start];
            return node;
        }
        int mid = (node.start + node.end) / 2;
        node.left = build(A, start, mid);
        node.right = build(A, mid + 1, end);
        node.min = Math.min(node.left.min, node.right.min);
        return node;
    }
    //查询线段树
    private int query(SegmentTreeNode node, int start , int end) {
        if(start > end) {
            return 0;
        }
        if(node.start == start && node.end == end) {
            return node.min;
        }
        int mid = (node.start + node.end) / 2;
        if(end <= mid) {
            return query(node.left, start, end);
        }
        else if(start > mid) {
            return query(node.right, start, end);
        }else {
            //求最小值
            return Math.min(query(node.left, start, mid), query(node.right, mid + 1, end));
        }
    }

相关文章

  • Java 算法 - 约翰的生意(线段树)

    题意 样例 1.解题思路   这是一道非常典型的线段树题。之前我也做过类似的题,Java 算法-区间求和I(线段树...

  • Java 算法-线段树的修改

      首先说明一下,看这个博客之前,最好有线段树的基本概念,比如说线段树的构造、线段树的查询之类的。最近在学习ANd...

  • 10.线段树(比较高级的数据结构)

    一、线段树(区间树)的概念 Segment Tree;线段树属于高级数据结构,经常出现在算法竞赛中为什么要使用线段...

  • Java 算法-区间求和I(线段树)

      我之前学过线段树,掌握的不是很牢固,而这道题是线段树,为了加深记忆,所以还是觉得有必要记录下来,就当是对线段树...

  • 数据结构与算法-线段树

    数据结构与算法-线段树 图片来自慕课网,liuyubobobo讲师的课程“玩转数据结构 从入门到进阶” 线段树介绍...

  • 算法笔记 - 线段树

    线段树的实现比较简单 时间复杂度 O(nlogn) 传统线段树一般用递归实现 线段树可以实现区间数值修改O(log...

  • 线段树

    昨天画了个把小时把lintcode上跟线段树的几道题用java做了一下。把线段树相关的几题都Accepted了。。...

  • 算法模板(七) 线段树

    线段树单点操作 线段树区间操作

  • 数据结构-线段树

    实现一个线段树 下面实现的线段树,有三个功能: 把数组构建成一颗线段树 线段树的修改 线段树的查询 303号问题 ...

  • 线段树系列之——区间更新

    第三篇线段树了——重点不在于解决题目,通过题目理解线段树才是重点 前面写了一篇关于线段树的单点更新,线段树的单点更...

网友评论

    本文标题:Java 算法 - 约翰的生意(线段树)

    本文链接:https://www.haomeiwen.com/subject/jkmkfftx.html