[Daily Coding Problem 293] Minimum Cost to Construct Pyramid with Stones

You have N stones in a row, and would like to create from them a pyramid. This pyramid should be constructed such that the height of each stone increases by one until reaching the tallest stone, after which the heights decrease by one. In addition, the start and end stones of the pyramid should each be one stone high.

You can change the height of any stone by paying a cost of 1 unit to lower its height by 1, as many times as necessary. Given this information, determine the lowest cost method to produce this pyramid.

For example, given the stones [1, 1, 3, 3, 2, 1], the optimal solution is to pay 2 to create [0, 1, 2, 3, 2, 1].

 

Solution.

If we are given a max height and its index in the stones array, then it is easy to get the cost in O(N) time.  

To get this max height and its index, we do the following.

1. build an increasing array of interval 1 from left to right, starting at 1. 

2. build an increasing array of interval 1 from right to left, starting at 1.

3. get the min of the above two arrays at the same indices and find the max of all these mins. This is the max possible height.

 

Both the runtime and space complexity are O(N).

public class ConstructPyramid {
    public static int minCost(int[] stones) {
        int n = stones.length;
        int[] left = new int[n], right = new int[n];
        left[0] = 1;
        for(int i = 1; i < n; i++) {
            left[i] = Math.min(left[i - 1] + 1, stones[i]);
        }
        right[n - 1] = 1;
        for(int i = n - 2; i >= 0; i--) {
            right[i] = Math.min(right[i + 1] + 1, stones[i]);
        }
        
        int maxHeight = 0, centerIdx = -1;
        for(int i = 0; i < n; i++) {
            int currHeight = Math.min(left[i], right[i]);
            if(currHeight > maxHeight) {
                maxHeight = currHeight;
                centerIdx = i;
            }
        }
        return getCost(stones, maxHeight, centerIdx);
    }
    private static int getCost(int[] stones, int maxHeight, int centerIdx) {
        int cost = 0, h = maxHeight;
        for(int i = centerIdx; i >=0; i--) {
            if(h > stones[i]) {
                return -1;
            }
            cost += stones[i] - h;
            if(h > 0) {
                h--;
            }
        }
        h = maxHeight - 1;
        for(int i = centerIdx + 1; i < stones.length; i++) {
            if(h > stones[i]) {
                return -1;
            }
            cost += stones[i] - h;
            if(h > 0) {
                h--;
            }
        }
        return cost;
    }
    public static void main(String[] args) {
        int[] stones = {1, 1, 3, 3, 2, 1};
        System.out.println(minCost(stones));
    }
}

 

转载于:https://www.cnblogs.com/lz87/p/11531034.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值