技術メモ

神奈川在住のITエンジニアの備忘録。おもにプログラミングやネットワーク技術について、学んだことを自分の中で整理するためにゆるゆると書いています。ちゃんと検証できていない部分もあるのでご参考程度となりますが、誰かのお役に立てれば幸いです。

leetCode : Apply Discount Every n Orders

leetCode の「Apply Discount Every n Orders」を解いてみた。
https://leetcode.com/problems/apply-discount-every-n-orders/

この問題は、商品の価格や割引の情報を受け取り、それに基づいて料金の計算をするというもの。なお、n 番目および n で割れる数番目のお客さんに対しては、割引を行う。
提出したコードは以下。特に工夫はしておらず、題意のまま実装した。

import java.util.HashMap;
import java.util.Map;

class Cashier {
    private int discountCustomerNum;
    private int discountRate;
    private Map<Integer, Integer> productIdToPrice = new HashMap<>();
    private int customerCount = 0;

    public Cashier(int n, int discount, int[] products, int[] prices) {
        discountCustomerNum = n;
        discountRate = discount;
        for (int i = 0; i < products.length; i++) {
            productIdToPrice.put(products[i], prices[i]);
        }
    }

    public double getBill(int[] product, int[] amount) {
        // マルチスレッド環境であれば、customerCountを守るために、getBill にsynchronizedをかけるべきだが、
        // この問題はシングルスレッド環境を想定しているようなので、これで良しとする。
        customerCount++;

        // 基本料金の計算
        double bill = 0;
        for (int i = 0; i < product.length; i++) {
            bill += productIdToPrice.get(product[i]) * amount[i];
        }

        // 割引額の計算
        if (customerCount % discountCustomerNum == 0) {
            double discount = bill * ((double) discountRate / 100);
            bill -= discount;
            customerCount = 0;
        }
        return bill;
    }
}

提出結果は以下となった。

Runtime: 108 ms, faster than 48.49% of Java online submissions for Apply Discount Every n Orders.
Memory Usage: 64 MB, less than 100.00% of Java online submissions for Apply Discount Every n Orders.

提出者の中で真ん中くらいの速度となった。
コメントにも書いたが、Cashier がマルチスレッドからアクセスされるのであれば、getBill にsynchronizedをかけるなどすべき。

この問題、leetCode では medium レベルにランクされているが、アルゴリズム的にはそんなに難しくない。この問題に限らず、「Design(設計)」にカテゴライズされている問題は、実装量がアルゴリズムだけの問題より多いので、medium レベルになっているような気がする。