Java 算法 - 約翰的生意(線(xiàn)段樹(shù))

題意

在一條數(shù)軸上,有n個(gè)城市,編號(hào)從0 ~ n – 1 , 約翰打算在這n個(gè)城市做點(diǎn)生意,他對(duì)Armani的一批貨物感興
趣,每個(gè)城市對(duì)于這批貨物都有一個(gè)價(jià)格prices[i]。對(duì)于城市x,約翰可從城市編號(hào)為[x - k, x + k]購(gòu)買(mǎi)貨物,然后
賣(mài)到城市x,問(wèn)約翰在每個(gè)城市最多能賺到多少錢(qián)?

樣例

給出 prices = [1, 3, 2, 1, 5], k = 2,返回 [0, 2, 1, 0, 4]。
解釋?zhuān)?i = 0,約翰可去的城市有0~2因?yàn)?、2號(hào)城市的價(jià)格比0號(hào)城市的價(jià)格高,所以賺不了錢(qián),即 ans[0] = 0。
i = 1,可去的城市有0~3,可以從0號(hào)或者3號(hào)城市購(gòu)買(mǎi)貨物賺取的差價(jià)最大,即ans[1] = 2。
i = 2,可去的城市有0~4,顯然從3號(hào)城市購(gòu)買(mǎi)貨物賺取的差價(jià)最大,即ans[2] = 1。
i = 3,可去的城市有1~4,沒(méi)有其他城市的價(jià)格比3號(hào)城市價(jià)格低,所以賺不了錢(qián),ans[3] = 0。
i = 4,可去的城市有2~4,從3號(hào)城市購(gòu)買(mǎi)貨物賺取的差價(jià)最大,即ans[4] = 4。

給出 prices = [1, 1, 1, 1, 1], k = 1, 返回 [0, 0, 0, 0, 0]。
解釋?zhuān)?所有城市價(jià)格都一樣,所以不能賺到錢(qián),即所有的ans都為0。

1.解題思路

??這是一道非常典型的線(xiàn)段樹(shù)題。之前我也做過(guò)類(lèi)似的題,Java 算法-區(qū)間求和I(線(xiàn)段樹(shù)),其實(shí)原理都是差不多的。重點(diǎn)在于構(gòu)建線(xiàn)段樹(shù),這里構(gòu)造的線(xiàn)段樹(shù),用來(lái)記錄每個(gè)區(qū)域的最小值。在最大的差價(jià)是,我只要在這個(gè)范圍找到最小值,然后求最小值就行了。

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;
        }

    }
    //構(gòu)建線(xiàn)段樹(shù)
    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;
    }
    //查詢(xún)線(xiàn)段樹(shù)
    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));
        }
    }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容