1. 程式人生 > 其它 >leetcode797題解_回溯法_看視訊和官方

leetcode797題解_回溯法_看視訊和官方

技術標籤:leetcode

參考:

B站參考視訊

leetcode官方解答

思路:

1:我沒想著自己能想出來,這方面我很新手,聽老師課堂上講和自己課後寫作業概念不一樣。

2:我依靠著視訊,將java邏輯變為了python在公司生產中小半部分實現(雖然慢的讓領導無法接受),這樣算是基本理解了。

3:後續對於生產來說應當是優化,解決了有無的問題。不算直接拿過來抄襲,但我感覺我還是有點無法理解,需要熟練度。

注意的點:

回溯模板按視訊裡面的邏輯分為3點,1是全域性變數,2是初始點,3是回溯函式,最經典的地方是回溯函式。

1:我在用python複寫時發現這個res可以不用宣告為全域性變數,區域性變數也可,只需要呼叫allPathSourceTarget時傳入一個區域性變數時即可,這樣做時避免多個使用者之間呼叫的互相干擾。(個人研究無所謂全域性不全域性,不過全域性變數更易閱讀。)

2:視訊裡面強調回溯函式裡面不要直接res.add(list),這樣會干擾結果,導致錯誤。我發現確實是這樣,找同事問了下,他宣告一個物件是對於傳入的list的深複製,故不干擾。(深、淺複製還是相當有用的,當然用c語言的指標來理解更加清晰。)

假如直接用list這個引用,兩東西綁在一起,自然不行。需要深複製區分開。(同事講的好!)

package com.arithmetic;

import java.util.ArrayList;
import java.util.List;

public class Medium797 {
    //1:回溯模板,首先將求得結果放外面當一個全域性變數
    List<List<Integer>> res = new ArrayList<>();
    
//    int[][] graph = {{1,2},{3},{3},{}};

    public  List<List<Integer>> allPathsSourceTarget(int[][] graph) {
        //2:初始點,題目預設給的是0
        List<Integer> list = new ArrayList<>();
        list.add(0);
        //3:進入到回溯函式裡面解決
        backtrace(graph, 0, list);
        return res;
    }

    private void backtrace(int[][] graph, int curr, List<Integer> list) {
        if(curr == graph.length - 1) {
//            res.add(list);不要這麼寫
            res.add(new ArrayList<Integer>(list));
            return;
        }
        for (int next: graph[curr]) {
            list.add(next);
            backtrace(graph, next, list);
            list.remove(list.size() - 1);
        }
//        for (int i = 0; i < graph[curr].length; i++) {
//            list.add(graph[curr][i]);
//            backtrace(graph, graph[curr][i], list);
//            list.remove(list.size() - 1);
//        }
    }
}
package com.arithmetic;

public class Test {
    public static void main(String[] args) {
        Medium797 exapmle = new Medium797();
        int[][] graph = {{1,2},{3},{3},{}};
        System.out.println(exapmle.allPathsSourceTarget(graph));
    }
}

複雜度分析,源於leetcode: