leetcode797題解_回溯法_看視訊和官方
阿新 • • 發佈:2021-02-06
技術標籤: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));
}
}