顯示具有 BFS 標籤的文章。 顯示所有文章
顯示具有 BFS 標籤的文章。 顯示所有文章

2019年11月13日 星期三

Alien Dictionary


Alien Dictionary

  • Lintcode : 892 / Leetcode : 269
  • Level : Hard

Problem

There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of non-empty words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language.

Example
Example 1:

Input:["wrt","wrf","er","ett","rftt"]
Output:"wertf"
Explanation:
from "wrt"and"wrf" ,we can get 't'<'f'
from "wrt"and"er" ,we can get 'w'<'e'
from "er"and"ett" ,we can get 'r'<'t'
from "ett"and"rftt" ,we can get 'e'<'r'
So return "wertf"

Example 2:

Input:["z","x"]
Output:"zx"
Explanation:
from "z" and "x",we can get 'z' < 'x'
So return "zx"
Notice
You may assume all letters are in lowercase.
You may assume that if a is a prefix of b, then a must appear before b in the given dictionary.
If the order is invalid, return an empty string.
There may be multiple valid order of letters, return the smallest in normal lexicographical order

Concept & Algorithm

Time Complexity & Space Complexity

time : O(string numbers * the index of avg different char position)
space: O(n)

Answer

/*
1. 利用suc存某字符的全部後缀,利用pre存某字符的全部前缀,chars存全部出現的字符。
2. 在建前缀和後缀map的過程中,s存上一個字串,t存當前字串,模擬字典序比较,按位比较,不相同说明當前字元是上個字串對應位置字元的後缀
3. head存拓樸排序當前的起点(即入度为0的字元,沒有前綴的意思),故首先遍歷pre,因為p.first一定有前缀,不能作起點,先從head中清除。
4. 每次取出head的頭部,即起點,加入答案中,然後清除,遍歷後缀,找連接起點的字元,刪除前綴,如果刪除後字元前缀為空,也可以成為起點,加入head。
*/
class Solution {
public:
    string alienOrder(vector<string> &words) {
        map<char, set<char>> suc, pre;
        set<char> chars;
        string s;
        for (string t : words) {
            chars.insert(t.begin(), t.end());
            for (int i = 0; i < min(t.size(), s.size()); i++) {
                char a = s[i], b = t[i];
                if (a != b) {
                    pre[b].insert(a);
                    suc[a].insert(b);
                    break;
                }
            }
            s = t;
        }

        set<char> head = chars;
        for (auto p : pre)
            head.erase(p.first);
        string order;
        while (head.size()) {
            auto it = head.begin();
            char c = *it;
            head.erase(c);
            order += c;
            for (auto i : suc[c]) {
                pre[i].erase(c);
                if (pre[i].empty()) {
                    head.insert(i);
                }
            }
        }
        // return order; -> false
        return order.size() == chars.size() ? order : "";
    }
};
tags: BFS
​

2019年11月12日 星期二

Sliding Puzzle II


Sliding Puzzle II

  • Lintcode : 794 / Leetcode : 773 similar
  • Level : Hard

Problem

On a 3x3 board, there are 8 tiles represented by the integers 1 through 8, and an empty square represented by 0.

A move consists of choosing 0 and a 4-directionally adjacent number and swapping it.

Given an initial state of the puzzle board and final state, return the least number of moves required so that the initial state to final state.

If it is impossible to move from initial state to final state, return -1.

Example
Example 1:

Input:
[
 [2,8,3],
 [1,0,4],
 [7,6,5]
]
[
 [1,2,3],
 [8,0,4],
 [7,6,5]
]
Output:
4

Explanation:
[                 [
 [2,8,3],          [2,0,3],
 [1,0,4],   -->    [1,8,4],
 [7,6,5]           [7,6,5]
]                 ]

[                 [
 [2,0,3],          [0,2,3],
 [1,8,4],   -->    [1,8,4],
 [7,6,5]           [7,6,5]
]                 ]

[                 [
 [0,2,3],          [1,2,3],
 [1,8,4],   -->    [0,8,4],
 [7,6,5]           [7,6,5]
]                 ]

[                 [
 [1,2,3],          [1,2,3],
 [0,8,4],   -->    [8,0,4],
 [7,6,5]           [7,6,5]
]                 ]
Example 2:

Input:
[[2,3,8],[7,0,5],[1,6,4]]
[[1,2,3],[8,0,4],[7,6,5]]
Output:
-1
Challenge
How to optimize the memory?
Can you solve it with A* algorithm?

Concept & Algorithm

Time Complexity & Space Complexity

time : O()
space: O()

Answer

class Solution {
public:
    int minMoveStep(vector<vector<int>> &init_state, vector<vector<int>> &final_state) {
        string initString = getString(init_state);
        string finalString = getString(final_state);

        queue<pair<string, int>> q;
        set<string> repeat;
        int index = getZeroPos(initString);
        q.push({initString, index});
        repeat.insert(initString);
        int step = 0;
        while (!q.empty()) {
            int size = q.size();
            for (int i = 0; i < size; i++) {
                pair<string, int> s = q.front(); q.pop();
                string res = s.first;
                int pos = s.second;

                if (res.compare(finalString) == 0) return step;
                for (auto d : dir) {
                    string str = res;
                    int x = pos / 3 + d[0];
                    int y = pos % 3 + d[1];
                    if (x < 0 || y < 0 || x >= 3 || y >= 3) continue;
                    int newIndex = x * 3 + y;
                    swap(str[newIndex], str[pos]);
                    if (repeat.find(str) != repeat.end()) continue;

                    q.push({str, newIndex});
                    repeat.insert(str);
                }
            }
            step++;
        }
        return -1;
    }
    vector<vector<int>> dir = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
    int getZeroPos (string &s) {
        for (int i = 0; i < 9; i++) {
            if (s[i] == '0') return i;
        }
    }
    string getString (vector<vector<int>> &str) {
        string res = "";
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                res.push_back('0' + str[i][j]);
            }
        }
        return res;
    }
};
tags: BFS
​

Binary Tree Level Order Traversal II


Binary Tree Level Order Traversal II

  • Lintcode : 70 / Leetcode : 107
  • Level : Medium

Problem

Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).

Example
Example 1:

Input:
{1,2,3}
Output:
[[2,3],[1]]
Explanation:
    1
   / \
  2   3
it will be serialized {1,2,3}
level order traversal
Example 2:

Input:
{3,9,20,#,#,15,7}
Output:
[[15,7],[9,20],[3]]
Explanation:
    3
   / \
  9  20
    /  \
   15   7
it will be serialized {3,9,20,#,#,15,7}
level order traversal

Concept & Algorithm

Time Complexity & Space Complexity

time : O(n)
space: O(n)

Answer

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode * root) {
        vector<vector<int>> ans;
        if (root == nullptr) return ans;
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty()) {
            int s = q.size();
            vector<int> res;
            for (int i = 0; i < s; i++) {
                TreeNode* p = q.front(); q.pop();
                res.push_back(p -> val);
                if (p -> left) q.push(p -> left);
                if (p -> right) q.push(p -> right);
            }
            ans.insert(ans.begin(), res);
        }
        return ans;
    }
};
tags: BFS
​

Binary Tree Zigzag Level Order Traversal


Binary Tree Zigzag Level Order Traversal

  • Lintcode : 71 / Leetcode : 103
  • Level : Medium

Problem

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).

Example
Example 1:

Input:{1,2,3}
Output:[[1],[3,2]]
Explanation:
    1
   / \
  2   3
it will be serialized {1,2,3}
Example 2:

Input:{3,9,20,#,#,15,7}
Output:[[3],[20,9],[15,7]]
Explanation:
    3
   / \
  9  20
    /  \
   15   7
it will be serialized {3,9,20,#,#,15,7}

Concept & Algorithm

Time Complexity & Space Complexity

time : O(n)
space: O(n)

Answer

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode * root) {
        int row = 1;
        vector<vector<int>> ans;
        if (root == nullptr) return ans;
        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            int s = q.size();
            vector<int> res;
            for (int i = 0; i < s; i++) {
                TreeNode* p = q.front(); q.pop();
                res.push_back(p -> val);
                if (p -> left) q.push(p -> left);
                if (p -> right) q.push(p -> right);
            }
            if (row % 2 == 0) {
                reverse(res.begin(), res.end());
            } 
            ans.push_back(res);
            row++;
        }
        return ans;
    }
};
tags: BFS
​

Connected Component in Undirected Graph


Connected Component in Undirected Graph

  • Lintcode : 431 / Leetcode : 323
  • Level : Medium

Problem

Find connected component in undirected graph.

Each node in the graph contains a label and a list of its neighbors.

(A connected component of an undirected graph is a subgraph in which any two vertices are connected to each other by paths, and which is connected to no additional vertices in the supergraph.)

You need return a list of label set.

Example
Example 1:

Input: {1,2,4#2,1,4#3,5#4,1,2#5,3}
Output: [[1,2,4],[3,5]]
Explanation:

  1------2  3
   \     |  | 
    \    |  |
     \   |  |
      \  |  |
        4   5
Example 2:

Input: {1,2#2,1}
Output: [[1,2]]
Explanation:

  1--2

Clarification
Learn more about representation of graphs

Notice
Nodes in a connected component should sort by label in ascending order. Different connected components can be in any order.

Concept & Algorithm

Time Complexity & Space Complexity

time : O(n)
space: O(n)

Answer

/**
 * Definition for Undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector<UndirectedGraphNode *> neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */

class Solution {
public:
    vector<vector<int>> connectedSet(vector<UndirectedGraphNode*> nodes) {
        set<UndirectedGraphNode*> repeat;
        vector<vector<int>> ans;
        for (auto n : nodes) {
            if (repeat.find(n) != repeat.end()) continue;
            bfs (n, repeat, ans);
        }
        return ans;
    }

    void bfs (UndirectedGraphNode* n, set<UndirectedGraphNode*> &repeat, vector<vector<int>> &ans) {
        if (n == nullptr) return;
        vector<int> res;
        queue<UndirectedGraphNode*> q;
        q.push(n);
        repeat.insert(n);
        while (!q.empty()) {
            UndirectedGraphNode* node = q.front(); q.pop();
            res.push_back(node -> label);
            for (auto neighbor : node -> neighbors) {
                if (repeat.find(neighbor) != repeat.end()) continue;
                q.push(neighbor);
                repeat.insert(neighbor);
            }
        }
        sort(res.begin(), res.end());
        ans.push_back(res);
    }
};
tags: BFS
​

Build Post Office II


Build Post Office II

  • Lintcode : 573 / Leetcode :
  • Level : Hard

Problem

Given a 2D grid, each cell is either a wall 2, an house 1 or empty 0 (the number zero, one, two), find a place to build a post office so that the sum of the distance from the post office to all the houses is smallest.

Return the smallest sum of distance. Return -1 if it is not possible.

Example
Example 1:

Input:[[0,1,0,0,0],[1,0,0,2,1],[0,1,0,0,0]]
Output:8
Explanation: Placing a post office at (1,1), the distance that post office to all the house sum is smallest.
Example 2:

Input:[[0,1,0],[1,0,1],[0,1,0]]
Output:4
Explanation: Placing a post office at (1,1), the distance that post office to all the house sum is smallest.
Challenge
Solve this problem within O(n^3) time.

Notice
You cannot pass through wall and house, but can pass through empty.
You only build post office on an empty.

Concept & Algorithm

Time Complexity & Space Complexity

time : O(m n mn)
space: O(m * n)

Answer

class Solution {
public:
    int shortestDistance(vector<vector<int>> &grid) {
        int house = 0;
        int m = grid.size(), n = grid[0].size();
        vector<vector<bool>> isVisited(m, vector<bool>(n, false));
        vector<vector<int>> stepSum(m, vector<int>(n));
        vector<vector<int>> houseNum(m, vector<int>(n));
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) {
                    bfs(grid, isVisited, stepSum, houseNum, i, j);
                    house += 1;
                }
            }
        }
        int minLen = INT_MAX;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 0 && houseNum[i][j] == house) {
                    minLen = min(minLen, stepSum[i][j]);
                }
            }
        }
        return minLen == INT_MAX ? -1 : minLen;
    }
    vector<vector<int>> dir = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    void bfs(vector<vector<int>> &grid, vector<vector<bool>> isVisited, vector<vector<int>> &stepSum, vector<vector<int>> &houseNum, int i, int j) {
        int step = 1;
        queue<vector<int>> q;
        q.push({i, j});
        isVisited[i][j] = true;
        while (!q.empty()) {
            int size = q.size();
            for (int k = 0; k < size; k++) {
                vector<int> pair = q.front(); q.pop();
                for (auto d : dir) {
                    int x = d[0] + pair[0];
                    int y = d[1] + pair[1];
                    if (!isValid(grid, x, y) || isVisited[x][y]) continue;
                    q.push({x, y});
                    isVisited[x][y] = true;
                    stepSum[x][y] += step;
                    houseNum[x][y] += 1;
                }
            }
            step++;
        }
    }
    bool isValid(vector<vector<int>> &grid, int x, int y) {
        if (x < 0 || y < 0 || x >= grid.size() || y >= grid[0].size() || grid[x][y] != 0)
            return false;
        return true;
    }
};
tags: BFS
​

2019年11月11日 星期一

Graph Valid Tree


Graph Valid Tree

  • Lintcode : 178 / Leetcode : 261
  • Level : Medium

Problem

Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.

Example
Example 1:

Input: n = 5 edges = [[0, 1], [0, 2], [0, 3], [1, 4]]
Output: true.
Example 2:

Input: n = 5 edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]
Output: false.
Notice
You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.

Concept & Algorithm

Time Complexity & Space Complexity

time : O(n)
space: O(n)

Answer

class Solution {
public:
    bool validTree(int n, vector<vector<int>> &edges) {
        // 判斷是否為tree 
        /*
            1. cycle
            2. edges = nodes - 1
        */
        map<int, unordered_set<int>> g;
        unordered_set<int> nodes;
        queue<int> q;
        // 因為不確定哪個會是parent
        // ex: 不一定是 [[0, 1]],可能是[[1, 0]]
        for (auto it : edges) {
            g[it[0]].insert(it[1]);
            g[it[1]].insert(it[0]);
        }
        q.push(0);
        nodes.insert(0);
        while (!q.empty()) {
            int node = q.front(); q.pop();
            for (auto a : g[node]) {
                // 有重複代表有cycle
                if (nodes.find(a) != nodes.end()) return false;
                q.push(a);
                nodes.insert(a);
                g[a].erase(node);
            }
        }
        // 避免 n 很多,但是沒有全部都拿來建構樹
        // ex: n = 3, edges = [[0, 1]]
        return nodes.size() == n;
    }
};
tags: BFS
​

Six Degrees


Six Degrees

  • Lintcode : 531 / Leetcode :
  • Level : Medium

Problem

Six degrees of separation is the theory that everyone and everything is six or fewer steps away, by way of introduction, from any other person in the world, so that a chain of "a friend of a friend" statements can be made to connect any two people in a maximum of six steps.

Given a friendship relations, find the degrees of two people, return -1 if they can not been connected by friends of friends.

Example
Example1

Input: {1,2,3#2,1,4#3,1,4#4,2,3} and s = 1, t = 4 
Output: 2
Explanation:
    1------2-----4
     \          /
      \        /
       \--3--/
Example2

Input: {1#2,4#3,4#4,2,3} and s = 1, t = 4
Output: -1
Explanation:
    1      2-----4
                 /
               /
              3

Concept & Algorithm

Time Complexity & Space Complexity

time : O(nodes * avg neighbors)
space: O(nodes)

Answer

/**
 * Definition for undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector<UndirectedGraphNode *> neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */

class Solution {
public:
    int sixDegrees(vector<UndirectedGraphNode*> graph, UndirectedGraphNode* s, UndirectedGraphNode* t) {
        map<UndirectedGraphNode*, int> degree;
        queue<UndirectedGraphNode*> q;
        q.push(s);
        degree[s] = 0;
        while (!q.empty()) {
            UndirectedGraphNode* n = q.front(); q.pop();
            if (n == t) return degree[t];
            for (auto j : n -> neighbors) {
                if (degree[j] != 0 && degree[j] <= degree[n] + 1) continue;
                degree[j] = degree[n] + 1;
                q.push(j);
            }
        }
        return -1;
    }
};
tags: BFS
​

Zombie in Matrix


Zombie in Matrix

  • Lintcode : 598 / Leetcode :
  • Level : Medium

Problem

Given a 2D grid, each cell is either a wall 2, a zombie 1 or people 0 (the number zero, one, two).Zombies can turn the nearest people(up/down/left/right) into zombies every day, but can not through wall. How long will it take to turn all people into zombies? Return -1 if can not turn all people into zombies.

Example
Example 1:

Input:
[[0,1,2,0,0],
 [1,0,0,2,1],
 [0,1,0,0,0]]
Output:
2
Example 2:

Input:
[[0,0,0],
 [0,0,0],
 [0,0,1]]
Output:
4

Concept & Algorithm

Time Complexity & Space Complexity

time : O(m n)
space: O(m
n) 最壞

Answer

class Solution {
public:
    int zombie(vector<vector<int>> &grid) {
        if (grid.size() == 0 || grid[0].size() == 0) return 0;
        queue<vector<int>> q;
        for (int i = 0; i < grid.size(); i++) {
            for (int j = 0; j < grid[0].size(); j++) {
                if (grid[i][j] == 1) q.push({i, j});
            }
        }
        int days = -1;
        while (!q.empty()) {
            int s = q.size();
            days += 1;
            for (int i = 0; i < s; i++) {
                vector<int> axis = q.front(); q.pop();
                for (auto d : dir) {
                    int x = d[0] + axis[0];
                    int y = d[1] + axis[1];
                    if (!isValid(grid, x, y)) continue;
                    q.push({x, y});
                    grid[x][y] = 1;
                }
            }
        }
        for (int i = 0; i < grid.size(); i++) {
            for (int j = 0; j < grid[0].size(); j++) {
                if (grid[i][j] == 0) return -1;
            }
        }
        return days;
    }
    vector<vector<int>> dir = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    bool isValid (vector<vector<int>> &grid, int x, int y) {
        if (x < 0 || y < 0 || x >= grid.size() || y >= grid[0].size() || grid[x][y] != 0)
            return false;
        return true;
    }
};
tags: BFS
​

Search Graph Nodes


Search Graph Nodes

  • Lintcode : 618 / Leetcode :
  • Level : Medium

Problem

Given a undirected graph, a node and a target, return the nearest node to given node which value of it is target, return NULL if you can't find.

There is a mapping store the nodes' values in the given parameters.

Example
Example 1:

Input:
{1,2,3,4#2,1,3#3,1,2#4,1,5#5,4}
[3,4,5,50,50]
1
50
Output:
4
Explanation:
2------3  5
 \     |  | 
  \    |  |
   \   |  |
    \  |  |
      1 --4
Give a node 1, target is 50

there a hash named values which is [3,4,10,50,50], represent:
Value of node 1 is 3
Value of node 2 is 4
Value of node 3 is 10
Value of node 4 is 50
Value of node 5 is 50

Return node 4
Example 2:

Input:
{1,2#2,1}
[0,1]
1
1
Output:
2
Notice
It's guaranteed there is only one available solution

Concept & Algorithm

Time Complexity & Space Complexity

time : O(nodes * avg edges)
space: O(n)

Answer

/**
 * Definition for Undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector<UndirectedGraphNode *> neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */

class Solution {
public:
     UndirectedGraphNode* searchNode(vector<UndirectedGraphNode*>& graph,
                                    map<UndirectedGraphNode*, int>& values,
                                    UndirectedGraphNode* node,
                                    int target) {
                                        if (node == nullptr) return nullptr;
                                        queue<UndirectedGraphNode*> q;
                                        q.push(node);
                                        set<UndirectedGraphNode*> repeat;
                                        while (!q.empty()) {
                                            UndirectedGraphNode* n = q.front(); q.pop();
                                                if (values[n] == target) return n;
                                                for (auto j : n -> neighbors) {
                                                    if (repeat.find(j) != repeat.end()) continue;
                                                    q.push(j);
                                                    repeat.insert(j);
                                                }
                                        }
                                        return nullptr;
    }
};
tags: BFS
​

Last Position of Target

Last Position of Target Lintcode : 458 / Leetcode : 34 Level : Easy Problem Find the last position of a target number in a sorted ...