ARTS是什麼?
Algorithm:每週至少作一個leetcode的算法題;
Review:閱讀並點評至少一篇英文技術文章;
Tip:學習至少一個技術技巧;
Share:分享一篇有觀點和思考的技術文章。html
LeetCode 126. Word Ladder IIjava
思路分析
這道題是一道經典的搜索問題,難點仍是在於優化。題目要求找出全部可能的解,咱們能夠把這道題轉化爲一個無向圖,每一個單詞表示的是圖上的節點,保證每一個單詞的鄰居單詞跟這個單詞只有一個字母的不一樣,若是用暴力的深度優先搜索,咱們在圖上選中起始節點和終止節點,考慮全部的從起點到終點的可能的路徑,這麼作會大大增長搜索所消耗的時間,那麼怎麼優化呢?和咱們以前經常提到的增長記憶化不一樣的是,這裏咱們考慮使用標記法,由於在搜索的時候,咱們要保證咱們當前的搜索方向是朝着終點去的,什麼意思,就是說,下一個咱們要去的節點到終點的距離要比到當前咱們所在節點到終點的距離更近,根據這麼一個思路咱們能夠進行兩次搜索,第一次僅僅是標記,第二次纔是搜索可能的答案。這裏標記使用的是廣度優先搜索,爲何不使用深度優先搜索?由於這個圖中可能存在環,深度優先搜索無法保證標記的正確性。搜索答案的時候咱們可使用深度優先搜索,也能夠廣度,這裏我使用了深搜。python
參考代碼算法
public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
if (beginWord.equals(endWord) || !wordList.contains(endWord)) {
return new ArrayList<>();
}
List<List<String>> results = new ArrayList<>();
// bfs mark
Map<String, Integer> memo = new HashMap<>();
for (String word : wordList) {
memo.put(word, -1);
}
memo.put(beginWord, -1);
memo.put(endWord, 0);
bfsMark(endWord, memo);
System.out.println(memo);
// dfs find path
List<String> path = new ArrayList<String>();
path.add(beginWord);
dfs(memo, beginWord, endWord, wordList, path, results, memo.get(beginWord));
return results;
}
private void dfs(Map<String, Integer> memo, String curWord, String endWord, List<String> wordList, List<String> path, List<List<String>> results, int step) {
if (curWord.equals(endWord)) {
results.add(new ArrayList<String>(path));
}
if (step <= 0) {
return;
}
for (String word : wordList) {
if (memo.get(word) == step - 1 && checkDiff(word, curWord)) {
path.add(word);
dfs(memo, word, endWord, wordList, path, results, step - 1);
path.remove(path.size() - 1);
}
}
}
private boolean checkDiff(String a, String b) {
int count = 0;
for (int i = 0; i < a.length(); ++i) {
if (a.charAt(i) != b.charAt(i)) {
count++;
}
if (count > 1) {
return false;
}
}
return count == 1;
}
private void bfsMark(String endWord, Map<String, Integer> memo) {
Queue<String> queue = new LinkedList<>();
queue.offer(endWord);
int stepCount = 0;
while (!queue.isEmpty()) {
int size = queue.size();
stepCount++;
for (int i = 0; i < size; ++i) {
String curWord = queue.poll();
char[] curWordArr = curWord.toCharArray();
for (char r = 'a'; r <= 'z'; ++r) {
for (int j = 0; j < curWordArr.length; ++j) {
char tmp = curWordArr[j];
curWordArr[j] = r;
String newWord = String.valueOf(curWordArr);
if (memo.containsKey(newWord) && memo.get(newWord) == -1) {
queue.offer(newWord);
memo.put(newWord, stepCount);
}
curWordArr[j] = tmp;
}
}
}
}
}
複製代碼
一篇關於如何問別人技術問題的文章:
bash
How To Ask Questions The Smart Way網絡
問問題也是一門學問,特別是在網上問問題,文章讀起來不是太好懂,但仍是理解了、學到了很多,總結一下重點內容:app
這周接觸了 openresty,記錄一下它在 Mac 上的安裝和啓動post
安裝(使用 homebrew):學習
>$ brew tap openresty/brew
>$ brew install openresty
複製代碼
啓動:測試
>$ openresty -p `...` -c ...
複製代碼
中止:
>$ openresty -s quit -p `...` -c ...
複製代碼
再來記錄幾個以前比較模糊,可是如今懂了的 Python 基礎知識點:
import copy
a = [[1,2],2,3,4]
b = copy.copy(a)
b.append(1)
b[0].append(3)
print(a)
print(b)
-----------------------------
[[1, 2, 3], 2, 3, 4]
[[1, 2, 3], 2, 3, 4, 1]
複製代碼
這周最後仍是來聊聊算法,拓撲排序