Pythonで目標の5つ星レビュー率に達するために必要な追加レビュー数を計算する方法
リスト reviews としきい値 t があるとします。reviews[i] の各要素は [x, y] という形式で表され、これは製品 i が x 件の5つ星評価と y 件のレビューを受け取っていることを意味します。ここでの課題は、レビュー全体に占める5つ星レビューの割合が少なくとも t % になるようにするために、追加で必要となる5つ星レビューの最小件数を求めることです。
たとえば、入力が reviews = [[3, 4], [1, 2], [4, 6]]、threshold = 78 である場合を考えてみましょう。このとき出力は 7 になります。現時点では5つ星レビューが合計8件、レビュー総数は12件あるためです。5つ星レビュー率を78%に到達させるには、あと7件の5つ星レビューが必要となります。
解決のためのアルゴリズム
この問題を解くには、以下の手順に従います。
変数 a を 0、b を 0 として初期化します。
reviews 内の各要素から、5つ星レビュー数 c とレビュー総数 d を取り出し、それぞれを加算していきます。
a := a + c
b := b + d
a * 100 >= t * b が成り立つ場合(すでにしきい値を満たしている場合)は、0 を返します。
delta := t * b - 100 * a を計算します。これは目標との差(不足分)を表す値です。
(delta + (99 - t)) / (100 - t) の小数点以下を切り捨てた値を返します。
最後の式は「切り上げ除算」を実現するためのテクニックです。追加するレビュー数は整数である必要があるため、割り算の結果に端数が出た場合は切り上げなければなりません。(delta + (99 - t)) // (100 - t) という形にすることで、余りが発生した際に自動的に繰り上がらせることができます。
実装例
理解を深めるために、以下のPythonによる実装を見てみましょう。
def solve(reviews, t):
a = 0
b = 0
for c, d in reviews:
a += c
b += d
if a * 100 >= t * b:
return 0
delta = t * b - 100 * a
return (delta + (99 - t)) // (100 - t)
reviews = [
[3, 4],
[1, 2],
[4, 6]
]
t = 78
print(solve(reviews, t))
入力
[[3, 4], [1, 2],[4, 6] ],78
出力
7
-
Pythonで文字列の異なる部分文字列の個数を数える方法(トライ木による解法)
文字列 s が与えられたとき、その中に含まれる「空でない異なる部分文字列」が何種類あるかを求める問題を考えてみましょう。例えば、入力が s = abaa の場合、出力は 8 になります。これは、部分文字列として [a, b, ab, ba, aa, aba, baa, abaa] の8種類が存在するためです。解法のアプローチ:トライ木(Trie)を使うこの問題は、トライ木と呼ばれるデータ構造を使うことで効率的に解くことができます。トライ木とは、文字列の集合を木構造で表現したもので、共通の接頭辞を持つ文字列同士が同じ経路を共有できるのが特徴です。これにより、重複する部分文字列を自動的にまとめて管
-
Pythonでn個のノードから構成できる二分探索木(BST)の数を求める方法
問題の概要互いに異なるn個のノードが与えられたとき、それらを二分探索木(BST:Binary Search Tree)として配置する方法が何通りあるかを求めることを考えます。二分探索木には「左部分木には常に親より小さい値が、右部分木には常に親より大きい値が格納される」という重要な性質があります。この問題を解くには、カタラン数(Catalan Number)を利用します。カタラン数 C(n) は、n個の異なるキーから構成できる二分探索木の総数を正確に表すことが知られています。計算式は次のとおりです。$$C(n)=\frac{(2n)!}{(n+1)!\times n!}$$例えば、入力が n =