前往
大廳
主題

LeetCode - 0780. Reaching Points 解題心得

Not In My Back Yard | 2023-12-31 12:00:05 | 巴幣 0 | 人氣 150

題目連結:


題目意譯:
給定四整數 sx, sy, tx, ty,如果可以將點 (sx, sy) 經由若干個操作之後變換成點 (tx, ty),則回傳真(True);反之,則回傳假(False)。

對於某個點 (x, y),其被允許的變換為 (x, x + y) 或是 (x + y, y)。

限制:
1 ≦ sx, sy, tx, ty ≦ 10 ^ 9



範例測資:
範例 1:
輸入: sx = 1, sy = 1, tx = 3, ty = 5
輸出: true
解釋:
一個可以將起點變換到目標點的序列為:
(1, 1) -> (1, 2)
(1, 2) -> (3, 2)
(3, 2) -> (3, 5)

範例 2:
輸入: sx = 1, sy = 1, tx = 2, ty = 2
輸出: false

範例 3:
輸入: sx = 1, sy = 1, tx = 1, ty = 1
輸出: true


解題思維:
我們將 (x + y, y) 之變換稱為 Dx 、(x, x + y) 之變換稱為 Dy。

可以看到不管 sx 與 sy 原先大小關係為何,只要做至少一次 Dx 之後,新的 X 座標必定大於 sy;同理,只要做至少一次 Dy 後,新的 Y 座標必大於 sx。
(這是因為題目保證 sx 和 sy 都至少是 1)

而我們可以將上面的 sx 、 sy 換成做任意次的 Dx 、 Dy 之後的「當前」座標值,也會得出類似的結論。

而這代表著如果可以從 (sx, sy) 變換到 (tx, ty),則代表著該變換序列要嘛是
增加 X → 增加 Y → 增加 X → 增加 Y → ……的順序(即先做若干次 Dx,再若干次 Dy,再接若干次 Dx,又再接若干次 Dy 等等),
要嘛是
增加 Y → 增加 X → 增加 Y → 增加 X → ……的順序。

而將上面的序列「反過來」可以看到對於 (tx, ty),該序列會是
減少 X → 減少 Y → 減少 X → 減少 Y → ……的順序,
又或是
減少 Y → 減少 X → 減少 Y → 減少 X → ……的順序
並且我們可以看到每一步的「減少」會把「被減少」的座標值變小到小於「不變」的座標值為止(原本「被減少」之前,該座標值會大於「不變」的座標值),除非這是最後一步。

這代表著我們只要看到 tx > sx 且 ty > sy,便可以藉由上面的來減少 tx 或 ty,即:
當 tx < ty 時,將 ty 替換成 ty - tx 直到新的 ty 小於 tx 為止。而這可以使用模運算來簡化,也就是說直接將 ty 替換成 ty % tx 即可。

當 tx > ty 時,與上同理,將 tx 替換成 tx % ty。
(注意,如果一開始 tx == ty,則代表著我們不可能從 (sx, sy) 變換成 (tx, ty),因為 sx 和 sy 都至少是 1)

重複以上步驟直到 tx == sx 或 ty == sy 為止。此時如果 tx < sx 或是 ty < sy,則代表著所求變換序列是不存在的;反之,剩下的情況就很簡單了,只要 ty - sy 可以被 tx 整除(當 tx == sx 時)又或是 tx - sx 可以被 ty 整除(當 ty == ty 時),則代表著所求變換序列存在;反之,則不存在。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作