Leetcode 1345. 跳躍遊戲 IV

Leetcode 1345. 跳躍遊戲 IV

題意:

給一個一維的數組,你從下標0開始出發,有三種操作:每次可以向左,右移動一位,或者移動到與自己數值相同的位置。

思路:

這類搜索求最短步數的解法是典型的bfs,注意這題數據的特殊性,裸bfs會超時。
這是因爲第三個操作枚舉所有相同數值的位置時候,如果出現很多
相同值的數值,光枚舉相同值時間複雜度會近似O(n),整體就變成O(n^2)。

這一步枚舉,可以把連續出現相同值的區間只保留左右兩個端點,起到搜索剪枝的作用。

代碼:

python

class Solution:
    def minJumps(self, arr) -> int:
        import collections
        n = len(arr)
        if n  == 1: return 0
        poss = collections.defaultdict(list)
        for index, value in enumerate(arr):
            if (index and arr[index]!= arr[index-1] or
                    (index < n-1 and arr[index]!=arr[index + 1])): # 剪枝
                poss[value] .append(index)
        que= collections.deque([(0,0)])
        vis = set([0])
        while que:
            pos, cur  = que.popleft()
            for nxt in poss[arr[pos]] + [pos+1 ,pos -1]:
                if nxt == n -1: return cur +1
                if 0 < nxt < n-1 and nxt not in vis:
                    que.append((nxt , cur+1))
                    vis.add(nxt)

c++

class Solution {
public:
    int minJumps(vector<int>& arr) {
        int n = arr.size();
        if(n==1) return 0;
        unordered_map<int, vector<int>> pos;
        for(int i =0 ;i<n;i++){
            if((i>0&&arr[i]!=arr[i-1])||(i<n-1&&arr[i]!=arr[i+1])){
                pos[arr[i]].push_back(i);
            }
        }
        queue<pair<int,int> > que;
        que.push(make_pair(0 ,0));
        set<int> vis;
        vis.insert(0);
        int ans =0 ;
        bool flag = false;
        while(!que.empty()){
            int p = que.front().first, cur = que.front().second;
            que.pop();
            for(int i=0;i<pos[arr[p]].size();i++){
                int nxt = pos[arr[p]][i];
                if((nxt == n-1)||(p+1 == n-1)){
                        ans = cur + 1;
                        flag = true;
                        break;
                }
                if(nxt>1&&nxt<n&&vis.count(nxt)==0){
                    que.push(make_pair(nxt, cur+1));
                    vis.insert(nxt);
                }
            }
            if(flag) break;
            if(p+1>0&&p+1<n&&vis.count(p+1)==0){
                que.push(make_pair(p+1, cur+1));
                vis.insert(p+1);
            }
            if(p-1>0&&p-1<n&&vis.count(p-1)==0){
                que.push(make_pair(p-1, cur+1));
                vis.insert(p-1);
            }
        }
        return ans;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章