![](/img/trans.png)
[英]I am Trying to solve a problem in hacker rank. My algorithm is okay but can't find the output
[英]Algorithm to solve a Hacker earth problem
我一直在研究 Hackerearth 問題。 這是問題陳述:
我們有三個變量 a、b 和 c。 我們需要將 a 轉換為 b 並且允許以下操作:
1.可以減1。
2.可以減2。
3. 可以乘以c。
將 a 轉換為 b 所需的最少步驟。
這是我想出的算法:
將計數增加到 0。
循環直到 a === b:
1. 執行 (x = a * c)、(y = a - 1) 和 (z = a - 2)。
2、在x、y、z中,選擇與b絕對差最小的那個。
3. 將 a 的值更新為在 x、y 和 z 中選擇的值。
4. 將計數加 1。
我可以通過基本測試用例,但我所有的高級用例都失敗了。 我想我的邏輯是正確的,但由於復雜性,它似乎失敗了。
有人可以建議更優化的解決方案。
編輯 1
示例代碼
function findMinStep(arr) {
let a = parseInt(arr[0]);
let b = parseInt(arr[1]);
let c = parseInt(arr[2]);
let numOfSteps = 0;
while(a !== b) {
let multiply = Math.abs(b - (a * c));
let decrement = Math.abs(b - (a - 1));
let doubleDecrement = Math.abs(b - (a - 2));
let abs = Math.min(multiply, decrement, doubleDecrement);
if(abs === multiply) a = a * c;
else if(abs === decrement) a -= 1;
else a -= 2;
numOfSteps += 1;
}
return numOfSteps.toString()
}
樣本輸入: a = 3,b = 10,c = 2
解釋: 3 乘以 2 得到 6,6 減 1 得到 5,5 乘以 2 得到 10。
對 Python 和 JS 都打上標簽的原因:兩者都適合,但我不是在尋找代碼,只是在尋找優化的算法和分析思維。
編輯2:
function findMinStep(arr) {
let a = parseInt(arr[0]);
let b = parseInt(arr[1]);
let c = parseInt(arr[2]);
let depth = 0;
let queue = [a, 'flag'];
if(a === b ) return 0
if(a > b) {
let output = Math.floor((a - b) / 2);
if((a - b) % 2) return output + 1;
return output
}
while(true) {
let current = queue.shift();
if(current === 'flag') {
depth += 1;
queue.push('flag');
continue;
}
let multiple = current * c;
let decrement = current - 1;
let doubleDecrement = current -2;
if (multiple !== b) queue.push(multiple);
else return depth + 1
if (decrement !== b) queue.push(decrement);
else return depth + 1
if (doubleDecrement !== b) queue.push(doubleDecrement);
else return depth + 1
}
}
仍然超時。 還有什么建議嗎?
問題鏈接供您參考。
貪婪的方法在這里不起作用。
然而,它已經在正確的軌道上。 考慮圖G
,其中每個節點代表一個值,每條邊代表一個操作,並連接與該操作相關的兩個值(例如:4 和 3 通過“減 1”連接)。 使用此圖,我們可以輕松執行BFS 搜索以找到最短路徑:
def a_to_b(a, b, c):
visited = set()
state = {a}
depth = 0
while b not in state:
visited |= state
state = {v - 1 for v in state if v - 1 not in visited} | \
{v - 2 for v in state if v - 2 not in visited} | \
{v * c for v in state if v * c not in visited}
depth += 1
return 1
這個查詢系統地測試所有可能的操作組合,直到它通過逐步測試到達b
。 即從a
生成可以通過單個操作達到的所有值,然后測試通過兩次操作可以達到的所有值,依此類推,直到b
在生成的值中。
(假設c >= 0
,但可以推廣)
到目前為止,對於幾乎沒有分析的標准方法。 這種方法的優點是它適用於任何此類問題並且易於實施。 但是,它的效率不是很高,並且一旦數字增長,就會相當快地達到極限。 因此,我將展示一種深入分析問題並獲得(遠遠)性能更高的解決方案的方法:
在第一步中,此答案將分析問題:
我們需要操作-->op
使得a -->op b
和-->op
是一個序列
c
首先,如果我們先減然后乘會發生什么?
(a - x) * c = a * c - x * c
如果我們先乘后減,接下來會發生什么?
a * c - x'
定位系統
好吧,這沒有簡化的轉換。 但是我們已經有了分析更復雜的操作鏈的基本部分。 讓我們看看當我們交替地鏈式減法和乘法時會發生什么:
(((a - x) * c - x') * c - x'') * c - x'''=
((a * c - x * c - x') * c - x'') * c - x''' =
(a * c^2 - x * c^2 - x' * c - x'') * c - x''' =
a * c^3 - x * c^3 - x' * c^2 - x'' * c - x'''
看起來很熟悉? 我們距離在基於c
的位置系統中定義a
和b
之間的差異僅一步之遙:
a * c^3 - x * c^3 - x' * c^2 - x'' * c - x''' = b
x * c^3 + x' * c^2 + x'' * c + x''' = a * c^3 - b
不幸的是,以上仍然不是我們所需要的。 我們只能說,方程的 LHS 將始終>=0
。 一般來說,我們首先需要推導出適當的指數n
(在上面的例子中為 3), st 它是最小的、非負的並且a * c^n - b >= 0
。 為單個系數 ( x
, x'
, ...) 解決這個問題,其中所有系數都是非負的,這是一項相當簡單的任務。
我們可以從上面展示兩件事:
a < b
且a < 0
,則無解最優性證明
上面的第二個陳述可以通過對n
的歸納來證明。
n = 0
: 在這種情況下a - b < c
,所以只有一個-->op
n + 1
:讓d = a * c^(n + 1) - b
。 令d' = d - m * c^(n + 1)
,其中選擇m
,使得d'
最小且非負。 每個歸納假設d'
可以通過位置系統最佳地生成。 留下正好m * c^n
的差異。 通過低階項不能比通過m / 2
減法更有效地覆蓋這種差異。
算法(TLDR 部分)
考慮a * c^n - b
作為數基c
並嘗試找到它的數字。 最后的數字應該有n + 1
位數字,其中每個數字代表一定數量的減法。 多個減法通過將減法值相加由一位數表示。 例如 5 表示-2 -2 -1
。 從最重要到最不重要的數字,該算法的操作如下:
c
並從 1. 與下一個數字重復例如:
a = 3, b = 10, c = 2
選擇 n = 2
a * c^n - b = 3 * 4 - 10 = 2
二進制中的 2 是執行 010 步:3 - 0 = 3, 3 * 2 = 6, 6 - 1 = 5, 5 * 2 = 10
或者
a = 2, b = 25, c = 6
選擇 n = 2
a * c^n - b = 47
47 基數 6 是 115
執行的步驟:2 - 1 = 1, 1 * 6 = 6, 6 - 1 = 5, 5 * 6 = 30, 30 - 2 - 2 - 1 = 25
在蟒蛇中:
def a_to_b(a, b, c):
# calculate n
n = 0
pow_c = 1
while a * pow_c - b < 0:
n += 1
pow_c *= 1
# calculate coefficients
d = a * pow_c - b
coeff = []
for i in range(0, n + 1):
coeff.append(d // pow_c) # calculate x and append to terms
d %= pow_c # remainder after eliminating ith term
pow_c //= c
# sum up subtractions and multiplications as defined by the coefficients
return n + sum(c // 2 + c % 2 for c in coeff)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.