Showing posts with label BFS. Show all posts
Showing posts with label BFS. Show all posts

Sunday, October 9, 2016

407. Trapping Rain Water II

I don't have any clue to solve the problem. I have to follow the top rated solution. The idea behind is
(1) Use minimum heap to store the height for most outer boarder and scan from the lowest height.
(2) For the top height in the heap (h1), we need to record the lowest height (it's the maxH in the code). (Why? Because it is the lowest height in the most out boundary, we expect it to grow only. If there is any height lower than current lowest height, it has trapped water.) If it has neighbor with lower height (h2), then the neighbor must be able to hold water (maxH - h2). Why? Because at this time the boundary has been updated and maxH is the lowest height so far, please see step (3).
(3) Mark the neighbor as visited and push it to the heap. Since the neighbor has been visited, the boundary is updated.
(4) repeat (2) - (3) until heap becomes empty.

1:  class Solution {  
2:  public:  
3:    int trapRainWater(vector<vector<int>>& heightMap) {  
4:      if (heightMap.empty()) return 0;  
5:      int rows = heightMap.size(), cols = heightMap[0].size();  
6:      priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> q;  
7:      vector<vector<bool>> visited(rows, vector<bool>(cols, false));  
8:      for (int i = 0; i < rows; i++) {  
9:        for (int j = 0; j < cols; j++) {  
10:          if (i == 0 || i == rows-1 || j == 0 || j == cols-1) {  
11:            q.push(make_pair(heightMap[i][j], i*cols+j));  
12:            visited[i][j] = true;  
13:          }  
14:        }  
15:      }  
16:      vector<pair<int,int>> dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};  
17:      int res = 0, maxH = INT_MIN;  
18:      while (!q.empty()) {  
19:        int height = q.top().first;  
20:        int i = q.top().second / cols, j = q.top().second % cols;  
21:        q.pop();  
22:        maxH = max(maxH, height);  
23:        for (int d = 0; d < dir.size(); d++) {  
24:          int ii = i + dir[d].first;  
25:          int jj = j + dir[d].second;  
26:          if (ii < 0 || jj < 0 || ii == rows || jj == cols || visited[ii][jj]) continue;  
27:          visited[ii][jj] = true;  
28:          if (heightMap[ii][jj] < maxH) res += maxH - heightMap[ii][jj];  
29:          q.push(make_pair(heightMap[ii][jj], ii*cols+jj));  
30:        }  
31:      }  
32:      return res;  
33:    }  
34:  };  

Wednesday, August 10, 2016

111. Minimum Depth of Binary Tree

I was computing the depth from bottom to top which means you’ll have many redundant calls because you call h times from the root to get the depth and you’ll call h-1 times again from the left child to a leaf. Actually the h-1 times can be avoided if we compute the depth from top to bottom.

1:  /**  
2:   * Definition for a binary tree node.  
3:   * struct TreeNode {  
4:   *   int val;  
5:   *   TreeNode *left;  
6:   *   TreeNode *right;  
7:   *   TreeNode(int x) : val(x), left(NULL), right(NULL) {}  
8:   * };  
9:   */  
10:  class Solution {  
11:  private:  
12:    int minD = INT_MAX;  
13:  public:  
14:    int minDepth(TreeNode* root) {  
15:      if (root == NULL) return 0;  
16:      helper(root, 1);  
17:      return minD;  
18:    }  
19:    void helper(TreeNode *root, int depth) {  
20:      if (root->left == NULL && root->right == NULL) { minD = min(minD, depth); return; }  
21:      if (root->left) helper(root->left, depth+1);  
22:      if (root->right) helper(root->right, depth+1);  
23:    }  
24:  };  

Sunday, August 7, 2016

102. Binary Tree Level Order Traversal

Not much to say. BFS can be applied here. Here is the code.

1:  /**  
2:   * Definition for a binary tree node.  
3:   * struct TreeNode {  
4:   *   int val;  
5:   *   TreeNode *left;  
6:   *   TreeNode *right;  
7:   *   TreeNode(int x) : val(x), left(NULL), right(NULL) {}  
8:   * };  
9:   */  
10:  class Solution {  
11:  public:  
12:    vector<vector<int>> levelOrder(TreeNode* root) {  
13:      vector<vector<int>> res;  
14:      if (root == NULL) return res;  
15:      queue<TreeNode*> q;  
16:      q.push(root);  
17:      while (!q.empty()) {  
18:        int sz = q.size();  
19:        vector<int> level;  
20:        for (int i = 0; i < sz; i++) {  
21:          TreeNode *node = q.front();  
22:          q.pop();  
23:          level.push_back(node->val);  
24:          if (node->left) q.push(node->left);  
25:          if (node->right) q.push(node->right);  
26:        }  
27:        res.push_back(level);  
28:      }  
29:      return res;  
30:    }  
31:  };  

Wednesday, August 3, 2016

126. Word Ladder II

I built my solution on top of problem 127 "Word Ladder". I use a hash map to store the prior string set of current string. The key is current string and the value is the prior string set. The reason I use unordered_set for prior strings is to avoid duplicates. The basic idea is to find the shortest transformation sequence first and then build the sequences by the hash map.

1:  class Solution {  
2:  private:  
3:    unordered_map<string, unordered_set<string>> mp;  
4:    queue<string> q;  
5:    vector<vector<string>> res;  
6:    vector<string> path;  
7:    int dist;  
8:  public:  
9:    vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {  
10:      dist = helper(start, end, dict);  
11:      if (dist) output(start, end);  
12:      return res;   
13:    }  
14:    int helper(string &start, string &end, unordered_set<string> &dict) {  
15:      dict.insert(start);  
16:      q.push(start);  
17:      path.push_back(end);  
18:      dist = 1;  
19:      while (!q.empty()) {  
20:        int n = q.size();  
21:        for (int i = 0; i < n; i++) {  
22:          dict.erase(q.front());  
23:          q.push(q.front());  
24:          q.pop();  
25:        }  
26:        for (int i = 0; i < n; i++) {  
27:          string word = q.front();  
28:          q.pop();  
29:          if (word == end) return dist;  
30:          addNeighbors(word, dict);  
31:        }  
32:        dist++;  
33:      }  
34:      return 0;  
35:    }  
36:    void addNeighbors(string word, unordered_set<string> &dict) {  
37:      string tmp = word;  
38:      for (int i = 0; i < word.size(); i++) {  
39:        char c = tmp[i];  
40:        for (int j = 0; j < 26; j++) {  
41:          tmp[i] = 'a' + j;  
42:          if (dict.count(tmp)) {  
43:            q.push(tmp);  
44:            mp[tmp].insert(word);  
45:          }  
46:        }  
47:        tmp[i] = c;  
48:      }  
49:    }  
50:    void output(string &start, string end) {  
51:      if (path.size() == dist) {  
52:        if (start == end) {  
53:          reverse(path.begin(), path.end());  
54:          res.push_back(path);  
55:          reverse(path.begin(), path.end());  
56:        }  
57:        return;  
58:      }  
59:      int n = mp[end].size();  
60:      for (auto it = mp[end].begin(); it != mp[end].end(); it++) {  
61:        string s = *it;  
62:        path.push_back(s);  
63:        output(start, s);  
64:        path.pop_back();  
65:      }  
66:    }  
67:  };  

Friday, July 15, 2016

317. Shortest Distance from All Buildings

I followed the top rated solution. We scan from each building and calculate the distance from every 0 to itself. This can be done by BFS. In the end, we'll get a cumulative distance matrix, i.e. distance[2][3] is the sum of distances from all reachable buildings to grid[2][3] (grid[2][3] must be 0). Take the example in the problem, the eventual distance matrix will be:

 x  - 9 - x - 9 -  x
 9  - 8 - 7 - 8 -  9
10 - 9 - x - 9 - 10

So it'll be easy to figure out that the minimum distance is 7. However, this is just not enough to get a right answer. I mentioned "reachable" buildings. Why I emphasize "reachable"? Let's see an example.

1 - 0 - 0 - 0 - 1                                                         x - 7 - 6 - 5 - x
0 - 2 - 0 - 2 - 0    we can get distance matrix as      1 - x - 7 - x - 1
2 - 0 - 1 - 0 - 2                                                         x - 1 - x - 1 - x

If we only return the minimum distance, we'll be wrong in this case because we can't reach all the buildings in some place. To solve it, we need to have another map to count the reachable buildings for each position. And when we check the distance, we need to make sure that place has the reachable buildings equal to total buildings.

1:  class Solution {  
2:  public:  
3:    int shortestDistance(vector<vector<int>>& grid) {  
4:      int row = grid.size();  
5:      if (row == 0) return 0;  
6:      int col = grid[0].size();  
7:      vector<pair<int, int>> dir = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};  
8:      vector<vector<int>> distances(row, vector<int>(col, 0));  
9:      vector<vector<int>> reach(row, vector<int>(col, 0));  
10:      int buildings = 0;  
11:      for (int i = 0; i < row; i++) {  
12:        for (int j = 0; j < col; j++) {  
13:          if (grid[i][j] == 1) {  
14:            int dist = 0;  
15:            buildings++;  
16:            queue<pair<int,int>> curQue, nextQue;  
17:            vector<vector<bool>> visited(row, vector<bool>(col, 0));  
18:            curQue.push(make_pair(i, j));  
19:            while (!curQue.empty()) {  
20:              dist++;  
21:              while(!curQue.empty()) {  
22:                pair<int,int> cur = curQue.front();  
23:                curQue.pop();  
24:                reach[cur.first][cur.second]++;  
25:                for (int k = 0; k < dir.size(); k++) {  
26:                  int ii = cur.first + dir[k].first;  
27:                  int jj = cur.second + dir[k].second;  
28:                  if (ii >= 0 && ii < row && jj >= 0 && jj < col && !visited[ii][jj] && grid[ii][jj] == 0) {  
29:                    nextQue.push(make_pair(ii, jj));  
30:                    distances[ii][jj] += dist;  
31:                    visited[ii][jj] = true;  
32:                  }  
33:                }  
34:              }  
35:              swap(curQue, nextQue);  
36:            }  
37:          }  
38:        }  
39:      }  
40:      int res = INT_MAX;  
41:      for (int i = 0; i < row; i++) {  
42:        for (int j = 0; j < col; j++) {  
43:          if (grid[i][j] == 0 && reach[i][j] == buildings)  
44:            res = min(res, distances[i][j]);  
45:        }  
46:      }  
47:      return res == INT_MAX ? -1 : res;  
48:    }  
49:  };  

When I revisited this problem, I used a concept of local distance and global distance which seems to be easier to understand.

1:  class Solution {  
2:  public:  
3:    int shortestDistance(vector<vector<int>>& grid) {  
4:      int rows = grid.size();  
5:      if (rows == 0) return -1;  
6:      int cols = grid[0].size();  
7:      queue<pair<int,int>> q;  
8:      vector<vector<int>> global_dist(rows, vector<int>(cols, 0));  
9:      vector<vector<int>> reachable(rows, vector<int>(cols, 0));  
10:      vector<pair<int, int>> dir = {{1,0}, {-1,0}, {0,1}, {0,-1}};  
11:      int buildings = 0;  
12:      for (int i = 0; i < rows; i++) {  
13:        for (int j = 0; j < cols; j++) {  
14:          if (grid[i][j] == 1) {  
15:            buildings++;  
16:            q.push(make_pair(i, j));  
17:            vector<vector<int>> local_dist(rows, vector<int>(cols, 0));  
18:            while (!q.empty()) {  
19:              int sz = q.size();  
20:              for (int k = 0; k < sz; k++) {  
21:                int x = q.front().first;  
22:                int y = q.front().second;  
23:                q.pop();  
24:                for (int d = 0; d < dir.size(); d++) {  
25:                  int xx = x + dir[d].first;  
26:                  int yy = y + dir[d].second;  
27:                  if (xx<0||xx==rows||yy<0||yy==cols||grid[xx][yy]!=0||local_dist[xx][yy]!=0) continue;  
28:                  local_dist[xx][yy] = local_dist[x][y] + 1;  
29:                  global_dist[xx][yy] += local_dist[xx][yy];  
30:                  reachable[xx][yy]++;  
31:                  q.push(make_pair(xx, yy));  
32:                }  
33:              }  
34:            }  
35:          }  
36:        }  
37:      }  
38:      int minDist = INT_MAX;  
39:      for (int i = 0; i < rows; i++) {  
40:        for (int j = 0; j < cols; j++) {  
41:          if (grid[i][j] == 0 && reachable[i][j] == buildings) {  
42:            minDist = min(minDist, global_dist[i][j]);  
43:          }  
44:        }  
45:      }  
46:      return minDist == INT_MAX ? -1 : minDist;  
47:    }  
48:  };  

Thursday, July 14, 2016

286. Walls and Gates

BFS solution. We can push all the gates into a queue first, and then start from the gate in the queue to traverse across the entire map by BFS. For each position in the queue, we check its neighbors. We only want to update its neighbor when it is "nearer" to its neighbor. "Nearer" means the distance store in the neighbor is larger than rooms[i][j]+1. The challenge here is how to know a position has been visited before. Since we increase distance by 1 for neighbors, so the trick we do here to check if the distance stored in the neighbor is less than current position plus one.

1:  class Solution {  
2:  public:  
3:    void wallsAndGates(vector<vector<int>>& rooms) {  
4:      int row = rooms.size();  
5:      if (row == 0) return;  
6:      int col = rooms[0].size();  
7:      vector<pair<int, int>> dir = {{1,0}, {-1,0}, {0,1}, {0,-1}};  
8:      queue<pair<int, int>> reach;  
9:      for (int i = 0; i < row; i++) {  
10:        for (int j = 0; j < col; j++) {  
11:          if (rooms[i][j] == 0) {  
12:            reach.push(make_pair(i, j));  
13:          }  
14:        }  
15:      }  
16:      while (!reach.empty()) {  
17:        int i1 = reach.front().first;  
18:        int j1 = reach.front().second;  
19:        reach.pop();  
20:        for (int k = 0; k < dir.size(); k++) {  
21:          int i2 = i1 + dir[k].first;  
22:          int j2 = j1 + dir[k].second;  
23:          if (i2 < 0 || j2 < 0 || i2 == row || j2 == col || rooms[i2][j2] <= rooms[i1][j1]+1) continue;  
24:          rooms[i2][j2] = rooms[i1][j1] + 1;  
25:          reach.push(make_pair(i2, j2));  
26:        }  
27:      }  
28:    }  
29:  };  

When I revisited this problem, I used BFS as following but it turns out much slower than the way I did in this post. Then I rechecked the implementation and realized that the solution in this post actually performs multi-end BFS which reduced the running time to O(2n*n). The way I did runs O(k*n*n) where k is the number of gates.

1:  class Solution {  
2:  public:  
3:    void wallsAndGates(vector<vector<int>>& rooms) {  
4:      int rows = rooms.size();  
5:      if (rows == 0) return;  
6:      int cols = rooms[0].size();  
7:      queue<pair<int,int>> q;  
8:      vector<pair<int,int>> dir = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};  
9:      for (int i = 0; i < rows; i++) {  
10:        for (int j = 0; j < cols; j++) {  
11:          if (rooms[i][j] == 0) {  
12:            q.push(make_pair(i, j));  
13:            while (!q.empty()) {  
14:              int n = q.size();  
15:              for (int k = 0; k < n; k++) {  
16:                int x = q.front().first;  
17:                int y = q.front().second;  
18:                q.pop();  
19:                for (int d = 0; d < dir.size(); d++) {  
20:                  int xx = x + dir[d].first;  
21:                  int yy = y + dir[d].second;  
22:                  if (xx<0 || xx==rows || yy<0 || yy==cols || rooms[xx][yy]==-1 || rooms[x][y]+1>=rooms[xx][yy]) continue;  
23:                  rooms[xx][yy] = rooms[x][y] + 1;  
24:                  q.push(make_pair(xx, yy));  
25:                }  
26:              }  
27:            }  
28:          }  
29:        }  
30:      }  
31:    }  
32:  };  

127. Word Ladder

You can image the wordList as a forest from the beginning word. Each word with one character difference from the beginning word becomes its child. Note, to avoid loop, we need to erase/tag the visited child from the wordList. After constructing this, we move down to traverse its children. And the same rule, i.e. each word with one character difference become the child. We can keep doing that until we find the ending word or we find nothing.

1:  class Solution {  
2:  public:  
3:    int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {  
4:      wordList.insert(endWord);  
5:      queue<string> visit;  
6:      addNeighbors(beginWord, wordList, visit);  
7:      int distance = 2;  
8:      while (!visit.empty()) {  
9:        int n = visit.size();  
10:        for (int i = 0; i < n; i++) {  
11:          string word = visit.front();  
12:          visit.pop();  
13:          if (word == endWord) return distance;  
14:          addNeighbors(word, wordList, visit);  
15:        }  
16:        distance++;  
17:      }  
18:      return 0;  
19:    }  
20:    void addNeighbors(string word, unordered_set<string>& wordList, queue<string> &visit) {  
21:      wordList.erase(word);  
22:      for (int i = 0; i < word.size(); i++) {  
23:        char c = word[i];  
24:        for (int j = 0; j < 26; j++) {  
25:          word[i] = 'a'+j;  
26:          if (wordList.find(word) != wordList.end()) {  
27:            visit.push(word);  
28:            wordList.erase(word);  
29:          }  
30:        }  
31:        word[i] = c;  
32:      }  
33:    }  
34:  };  

Saturday, July 2, 2016

133. Clone Graph

The intuition is to use DFS/BFS. I'm using DFS here. We should note that nodes are uniquely labeled which indicates that we can use label to set up a hash table. So the key-value pair will be the label and the new node. The reason we want to use hash table is to avoid duplicates. For example, we have <0, 1>. So for 0, it has neighbor 1 and for 1 it has neighbor 0. When we start from 0, we'll copy a node of 0 and then visit 1. When visiting 1, we know there's 0 but at that time, we don't want to copy 0 again as we already did. All we want to do it just push the pointer to 1's neighbor list.

1:  /**  
2:   * Definition for undirected graph.  
3:   * struct UndirectedGraphNode {  
4:   *   int label;  
5:   *   vector<UndirectedGraphNode *> neighbors;  
6:   *   UndirectedGraphNode(int x) : label(x) {};  
7:   * };  
8:   */  
9:  class Solution {  
10:  public:  
11:    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {  
12:      if (node == NULL) return NULL;  
13:      unordered_map<int, UndirectedGraphNode*> visited;  
14:      return dfs(node, visited);  
15:    }  
16:    UndirectedGraphNode *dfs(UndirectedGraphNode *node, unordered_map<int, UndirectedGraphNode*> &visited) {  
17:      UndirectedGraphNode *newNode = new UndirectedGraphNode(node->label);  
18:      visited[node->label] = newNode;  
19:      for (UndirectedGraphNode* n : node->neighbors) {  
20:        if (!visited[n->label]) {  
21:          newNode->neighbors.push_back(dfs(n, visited));  
22:        } else {  
23:          newNode->neighbors.push_back(visited[n->label]);  
24:        }  
25:      }  
26:      return newNode;  
27:    }  
28:  };  

Here is the BFS way.

1:  /**  
2:   * Definition for undirected graph.  
3:   * struct UndirectedGraphNode {  
4:   *   int label;  
5:   *   vector<UndirectedGraphNode *> neighbors;  
6:   *   UndirectedGraphNode(int x) : label(x) {};  
7:   * };  
8:   */  
9:  class Solution {  
10:  public:  
11:    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {  
12:      if (node == NULL) return NULL;  
13:      unordered_map<UndirectedGraphNode *, UndirectedGraphNode *> mp;  
14:      UndirectedGraphNode *root = new UndirectedGraphNode(node->label);  
15:      mp[node] = root;  
16:      queue<UndirectedGraphNode *> q;  
17:      q.push(node);  
18:      while(!q.empty()) {  
19:        UndirectedGraphNode *cur = q.front();  
20:        q.pop();  
21:        for (UndirectedGraphNode *neighbor : cur->neighbors) {  
22:          if (mp.find(neighbor) == mp.end()) {  
23:            UndirectedGraphNode *copy = new UndirectedGraphNode(neighbor->label);  
24:            mp[neighbor] = copy;  
25:            q.push(neighbor);  
26:          }  
27:          mp[cur]->neighbors.push_back(mp[neighbor]);  
28:        }  
29:      }  
30:      return root;  
31:    }  
32:  };  

When I revisited this problem again, I found a more concise DFS way.

1:  /**  
2:   * Definition for undirected graph.  
3:   * struct UndirectedGraphNode {  
4:   *   int label;  
5:   *   vector<UndirectedGraphNode *> neighbors;  
6:   *   UndirectedGraphNode(int x) : label(x) {};  
7:   * };  
8:   */  
9:  class Solution {  
10:  private:  
11:    unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> mp;  
12:  public:  
13:    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {  
14:      if (node == NULL) return NULL;  
15:      UndirectedGraphNode *root = new UndirectedGraphNode(node->label);  
16:      mp[node] = root;  
17:      for (UndirectedGraphNode *n : node->neighbors) {  
18:        if (mp.find(n) == mp.end()) root->neighbors.push_back(cloneGraph(n));  
19:        else root->neighbors.push_back(mp[n]);  
20:      }  
21:      return root;  
22:    }  
23:  };  

Friday, July 1, 2016

310. Minimum Height Trees

Since this undirected graph has tree characteristics, any node in the graph can be a root and the graph mustn't have cycle. Since every node can be a root, the root with minimum height must have maximum leaves. So the problem becomes trimming the leaves level by level. The intuition about the level by level traversal is BFS. And yes, this problem can be solved by BFS.

However, when implementing, there are many places that are easy to make mistakes. I've highlighted them with red.

1:  class Solution {  
2:  public:  
3:    vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {  
4:      vector<unordered_set<int>> adj(n);  
5:      vector<int> cur;  
6:      for (int i = 0; i < edges.size(); i++) {  
7:        adj[edges[i].first].insert(edges[i].second);  
8:        adj[edges[i].second].insert(edges[i].first);  
9:      }  
10:      for (int i = 0; i < n; i++) {  
11:        if (adj[i].size() == 1) {  
12:          cur.push_back(i);  
13:        }  
14:      }  
15:      if (n == 1) {  
16:        cur.push_back(0);  
17:        return cur;  
18:      }  
19:      while (true) {  
20:        vector<int> next;  
21:        for (int i : cur) {  
22:          for (int j : adj[i]) {  
23:            adj[j].erase(i);  
24:            if (adj[j].size() == 1) next.push_back(j);  
25:          }  
26:        }  
27:        if (next.empty()) break;  
28:        cur = next;  
29:      }  
30:      return cur;  
31:    }  
32:  };  

(1) this is an undirected graph, the adjacent list should reflect this.
(2) To check if a node is a leaf, we need to check the size of unordered_set is 1 (not 0) because the set should only include its parent.
(3) It's better to use for loop in the way above as it's more clear and also a convention to iterate unordered_set.

Sunday, June 26, 2016

103. Binary Tree Zigzag Level Order Traversal

Typical level order traversal problem. We only need to keep a variable to know if we need to print from left to right or vice versa.

1:  /**  
2:   * Definition for a binary tree node.  
3:   * struct TreeNode {  
4:   *   int val;  
5:   *   TreeNode *left;  
6:   *   TreeNode *right;  
7:   *   TreeNode(int x) : val(x), left(NULL), right(NULL) {}  
8:   * };  
9:   */  
10:  class Solution {  
11:  public:  
12:    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {  
13:      vector<vector<int>> res;  
14:      if (root == NULL) return res;  
15:      queue<TreeNode*> que;  
16:      bool ltor = true;  
17:      que.push(root);  
18:      while (!que.empty()) {  
19:        int n = que.size();  
20:        vector<int> row(n, 0);  
21:        for (int i = 0; i < n; i++) {  
22:          TreeNode *node = que.front();  
23:          que.pop();  
24:          int pos = ltor ? i : n-i-1;  
25:          row[pos] = node->val;  
26:          if (node->left) que.push(node->left);  
27:          if (node->right) que.push(node->right);  
28:        }  
29:        ltor = !ltor;  
30:        res.push_back(row);  
31:      }  
32:      return res;  
33:    }  
34:  };  

Thursday, June 23, 2016

199. Binary Tree Right Side View

First of all, my solution takes level-order traversal (BFS).

1:  class Solution {  
2:  public:  
3:    vector<int> rightSideView(TreeNode* root) {  
4:      vector<int> res;  
5:      vector<TreeNode*> cur;  
6:      if (root == NULL) return res;  
7:      cur.push_back(root);  
8:      while (!cur.empty()) {  
9:        vector<TreeNode*> next;  
10:        for (int i = 0; i < cur.size(); i++) {  
11:          if (cur[i]->left) next.push_back(cur[i]->left);  
12:          if (cur[i]->right) next.push_back(cur[i]->right);  
13:        }  
14:        res.push_back(cur[cur.size()-1]->val);  
15:        cur = next;  
16:      }  
17:      return res;  
18:    }  
19:  };  

Top voted uses DFS, i.e. traverse right child first and then left right. Save value only when current output size is less than level size.

1:  class Solution {  
2:  public:  
3:    vector<int> rightSideView(TreeNode* root) {  
4:      vector<int> res;  
5:      helper(root, 1, res);  
6:      return res;  
7:    }  
8:    void helper(TreeNode *root, int level, vector<int> &res) {  
9:      if (root == NULL) return;  
10:      if (res.size() < level) {  
11:        res.push_back(root->val);  
12:      }  
13:      helper(root->right, level+1, res);  
14:      helper(root->left, level+1, res);  
15:      return;  
16:    }  
17:  };