題目解析
題目意思很簡單,就是給你一個二叉樹,然後告訴你每個節點都是有位置資訊的,即每個節點可以用(x,y)來表示。然後節點位置資訊為(x,y)的節點的左節點位置為(x+1,y-1),右節點位置為(x+1,y+1)。並且根節點的位置資訊統一為(0,0)
現在你需要像掃描表格一樣,從上往下,從左往右的順序遍歷。
解題思路
要求的順序是從上往下,從左往右,並且如果位置相同,就按節點值從小到大排。那麼能決定順序的就是兩個資訊,一個是節點的座標資訊,一個是節點的值資訊。顯然是需要對一個pair<座標,節點值>進行排序。其中座標可以用一個point(x,y)來表示。
排序規則
pair型別有一個預設排序規則,就是先比較first,如果first相等,則再比較second。
正好符合"如果位置相同,就按節點值從小到大排"的約定
point的比較,需要滿足“從上往下,從左往右”的約定
所以應該是先比較point.y,然後再比較point.x
演算法實現
- 將二叉樹轉換成
vector<pair<point,int>>
- 將上一步產生的容器排序
- 合併同一列的值組合成
vector<vector<int>>
- 返回結果
程式碼
class point
{
public:
int x;
int y;
point(int _x, int _y) :x(_x), y(_y) {};
};
bool operator<(const point& left,const point& right)
{
return (left.y < right.y) || (left.y == right.y) && (left.x < right.x);
}
bool operator==(const point& left, const point& right)
{
return (left.x == right.x && left.y == right.y);
}
ostream& operator<<(ostream& output, const point& p) // 列印輸出,以便檢視
{
output << "(" << p.x << "," << p.y << ")";
return output;
}
bool PairCompare(const pair<point, int>& left, const pair<point, int>& right)
{
return (left.first < right.first) || ((left.first == right.first) && (left.second < right.second));
}
class Solution {
vector<pair<point, int>> vec;
void bfs(TreeNode* node, point p)
{
if (!node)
return;
bfs(node->left, point(p.x + 1, p.y - 1));
vec.push_back(make_pair(p, node->val));
bfs(node->right, point(p.x + 1, p.y + 1));
}
public:
vector<vector<int>> verticalTraversal(TreeNode* root) {
vector<vector<int>> ans;
if (!root)
return ans;
bfs(root, point(0, 0));
sort(vec.begin(), vec.end(), PairCompare);
/* 輸出排序結果
for (auto x : vec)
{
cout << "point: " << x.first;
cout << "val: " << x.second << endl;
}
*/
auto prePair = vec.begin();
vector<int> tmpVec;
tmpVec.push_back(prePair->second);
for (auto it = vec.begin() + 1; it != vec.end(); ++it)
{
if (it->first.y == prePair->first.y)
{
tmpVec.push_back(it->second);
}
else
{
ans.push_back(tmpVec);
tmpVec.clear();
tmpVec.push_back(it->second);
prePair = it;
}
}
ans.push_back(tmpVec);
return ans;
}
};