Deklarata e problemit
Duke pasur parasysh një grup numrash të plotë jo-negativë numra, ju jeni pozicionuar fillimisht në indeksin e parë të grupit.
Çdo element në grup përfaqëson gjatësinë tuaj maksimale të kërcimit në atë pozicion.
Qëllimi juaj është të arrini indeksin e fundit në numrin minimal të kërcimeve.
Ju mund të supozoni se gjithmonë mund të arrini indeksin e fundit.
Deklarata e problemit është marrë nga: https://leetcode.com/problems/jump-game-ii/
Shembulli 1:
Input: nums = [2, 3, 1, 1, 4]
Output: 2
Explanation: The minimum number of jumps to reach the last index is 2. Jump 1 step from index 0 to 1, then 3 steps to the last index.
Shembulli 2:
Input: nums = [2, 3, 0, 1, 4]
Output: 2
Kufizimet:
- 1 <= nums.length <= 10^4
- 0 <= nums[i] <= 1000
Shpjegim
Problemi është një zgjatje e postimit tonë të vjetër në blog "Jump Game". Në problemin Jump Game, duhej të llogarisnim nëse mund të arrijmë indeksin e fundit të grupit apo jo. Në këtë problem, ne duhet të llogarisim numrin minimal të kërcimeve.
Qasja Brute Force
Qasja naive është zgjidhja e problemit duke përdorur rekursion. Rasti bazë në këtë rekursion do të ndodhë kur të arrijmë indeksin e fundit.
Ne do të thërrasim në mënyrë rekursive për të gjithë elementët e arritshëm nga elementi i parë. Kjo do të thotë që ne do të eksplorojmë të gjitha degët në pirgun e rekursionit dhe do të kthejmë numrin minimal të kërcimeve për të arritur indeksin e fundit.
Një fragment C++ i kësaj qasjeje është si më poshtë:
int minJumps(vector<int> &nums, int index){ if(index >= nums.size() - 1) return 0;
int jumps = INT_MAX;
for(int index = index + 1; i <= index + nums[index]; i++) jumps = min(jumps, 1 + minJumps(nums, i));
return jumps; }
Kompleksiteti kohor i qasjes së mësipërme është O(2^N), dhe kompleksiteti i hapësirës është O(1).
Programimi dinamik
Duke përdorur programimin dinamik, ne mund ta reduktojmë kompleksitetin kohor në O(N²). Qasja naive ka nënprobleme të mbivendosura dhe rezultatet e tyre ruhen në një grup. Gjatë llogaritjes së kërcimit minimal për nyjen, kontrollojmë nëse rezultati është i pranishëm në grupin e ruajtur apo jo.
Një fragment C++ i kësaj qasjeje është si më poshtë:
int jump(vector<int>& nums) { int n = nums.size(); vector<int> store(n); store[0] = 0;
for(int i = 1; i < n; i++) { store[i] = INT_MAX;
for(int j = 0; j < i; j++) { if(i <= nums[j] + j && store[j] != INT_MAX){ store[i] = min(store[i], store[j] + 1); break; } } }
return store[n - 1]; }
Kompleksiteti kohor i qasjes së mësipërme është O(N²) dhe kompleksiteti i hapësirës është O(n).
Qasje optimale e babëzitur
Në këtë qasje, ne përdorim një algoritëm të babëzitur që bën një zgjedhje optimale në çdo hap. Në çdo indeks, ne përcaktojmë hapat e ardhshëm që do të na afrojnë indeksit të fundit.
Le të kontrollojmë së pari algoritmin.
- set count, current, farthest = 0, 0, 0
- if nums[0] == 0 || nums.length == 1 - return 0
- loop for i = 0; i < nums.length; i++ - if nums[i] + i > farthest - set farthest = nums[i] + i
- if i == current - increment count: count++ - current = farthest
- for end
- return count
Le të kontrollojmë zgjidhjet tona në C++, Golang dhe Javascript.
Zgjidhja C++
class Solution { public: int jump(vector<int>& nums) { int count = 0, current = 0, farthest = 0;
if(nums[0] == 0 || nums.size() == 1) { return 0; }
for(int i = 0; i < nums.size() - 1; i++) { if(nums[i] + i > farthest) { farthest = nums[i] + i; }
if(i == current) { count++; current = farthest; } }
return count; } };
Zgjidhja Golang
func jump(nums []int) int { count, current, farthest := 0, 0, 0
if nums[0] == 0 || len(nums) == 1 { return 0 }
for i := 0; i < len(nums) - 1; i++ { if nums[i] + i > farthest { farthest = nums[i] + i }
if i == current { count++ current = farthest } }
return count }
Zgjidhje Javascript
var jump = function(nums) { let count = 0, current = 0, farthest = 0;
if(nums[0] == 0 || nums.length == 1) { return 0; }
for(let i = 0; i < nums.length - 1; i++) { if(nums[i] + i > farthest) { farthest = nums[i] + i; }
if(i == current) { count++; current = farthest; } }
return count; };
Le të ekzekutojmë algoritmin tonë për një hyrje të caktuar.
Input: nums = [2, 3, 1, 1, 4]
Step 1: count = 0 current = 0 farthest = 0
Step 2: if nums[0] == 0 || nums.length == 1 2 == 0 || 5 == 1 false
Step 3: loop for i = 0; i < nums.length - 1; i++ i < nums.length - 1 0 < 5 - 1 0 < 4 true
if nums[i] + i > farthest nums[0] + 0 > 0 2 + 0 > 0 true
farthest = nums[i] + i = 2
if i == current 0 == 0 true
count++ count = 1
current = farthest = 2
i++ i = 1
Step 4: loop for i < nums.length - 1 i < nums.length - 1 1 < 5 - 1 1 < 4 true
if nums[i] + i > farthest nums[1] + 1 > 2 3 + 1 > 2 true
farthest = nums[i] + i = 4
if i == current 1 == 2 false
i++ i = 2
Step 5: loop for i < nums.length - 1 i < nums.length - 1 2 < 5 - 1 2 < 4 true
if nums[i] + i > farthest nums[2] + 2 > 4 1 + 2 > 4 false
if i == current 2 == 2 true
count++ count = 2
current = farthest = 4
i++ i = 3
Step 6: loop for i < nums.length - 1 i < nums.length - 1 3 < 5 - 1 3 < 4 true
if nums[i] + i > farthest nums[3] + 3 > 4 1 + 1 > 4 false
if i == current 3 == 4 false
i++ i = 4
Step 7: loop for i < nums.length - 1 i < nums.length - 1 4 < 5 - 1 4 < 4 false
Step 8: return count
We return the answer as 2.
Botuar fillimisht në https://alkeshghorpade.me.
Nëse ky postim ishte i dobishëm, ju lutemi klikoni butonin duartrokas 👏 më poshtë disa herë për të treguar mbështetjen tuaj për autorin 👇