Find a number in minimum steps(Level Order Traversal)(层序遍历)(BFS)
Given an infinite number line from -INFINITY to +INFINITY and we are on zero. We can move n steps either side at each n’th time.
1st time; we can move only 1 step to both ways, means -1 1;
2nd time we can move 2 steps from -1 and 1;
-1 : -3 (-1-2) 1(-1+2)
1 : -1 ( 1-2) 3(1+2)
3rd time we can move 3 steps either way from -3, 1, -1, 3
-3: -6(-3-3) 0(-3+3)
1: -2(1-3) 4(1+3)
-1: -4(-1-3) 2(-1+3)
3: 0(0-3) 6(3+3)
Find the minimum number of steps to reach a given number n.
Examples:
Input : n = 10
Output : 4
We can reach 10 in 4 steps, 1, 3, 6, 10
Input : n = 13
Output : 5
We can reach 10 in 4 steps, -1, 2, 5, 9, 14
This problem can be modeled as tree. We put initial point 0 at root, 1 and -1 as children of root. Next level contains values at distance 2 and so on.
0
/ \
-1 1
/ \ / \
1 -3 -1 3
/ \ / \ / \ / \
The problem is now to find the closes node to root with value n. The idea is to do Level Order Traversal of tree to find the closest node. Note that using DFS for closest node is never a good idea (we may end up going down many unnecessary levels).
Below is C++ implementation of above idea.
思路一:将树的每个节点定义为结构体,包含值和位于的层数。
1 #include <iostream> 2 #include <queue> 3 #include <cstdlib> 4 using namespace std; 5 #define Inf 9999 6 7 // To represent data of a node in tree 8 struct number{ 9 int val; 10 int level; 11 public: 12 number(){} 13 number(int n, int l):val(n),level(l) {} 14 }; 15 16 void FindMiniSteps(int n){ 17 queue<number> que; 18 struct number r(0, 1); 19 que.push(r); 20 while(!que.empty()){ 21 // Remove a node from queue 22 struct number temp = que.front(); 23 que.pop(); 24 // To avoid infinite loop 25 if(temp.val > Inf || temp.val < -Inf) 26 break; 27 // Check if dequeued number is same as n 28 if(temp.val == n){ 29 cout << "Found number n at level " << temp.level-1 << endl; 30 break; 31 } 32 // Insert children of dequeued node to queue 33 que.push(number(temp.val-temp.level, temp.level+1));//先判断temp.val-temp.level == n,若相等则直接输出并结束 34 que.push(number(temp.val+temp.level, temp.level+1));//这里也可以优化 35 36 } 37 } 38 39 40 int main(){ 41 FindMiniSteps(13); 42 FindMiniSteps(10); 43 system("pause"); 44 return 0; 45 }
思路二:树的每个节点只包含一个数。
1 #include <iostream> 2 #include <queue> 3 #include <cstdlib> 4 using namespace std; 5 #define Inf 9999 6 7 void FindMiniSteps(int n){ 8 queue<int> que; 9 int flag = 0; 10 int step = 1; 11 que.push(0); 12 while(!que.empty()){ 13 int size = que.size();//记录第step层的元素个数 14 for(int i = 0; i < size; i++){//查找第step层是否有和n相等的数,若有则输出step-1,结束 15 int a = que.front(); 16 que.pop(); 17 if(a == n){ 18 flag = 1;//找到步数,结束,标记为1 19 cout << "Found number n at level " << step-1 << endl; 20 break; 21 } 22 que.push(a - step);//将a-step值放入队列,这里也可以先判断a-step ?= n,如果相等则可以直接输出,结束, 23 //特别是如果a为某一层最后一个元素时,如果a-step == n,则可以提前结束,而不用比较下一层的很多元素和把下下层的元素放入队列中 24 que.push(a + step);//将a+step值放入队列,这里也可以先判断a+step ?= n,如果相等则可以直接输出,结束 25 } 26 if(flag == 1)//如果flag == 1,结束 27 break; 28 step++;//下一层 29 } 30 } 31 32 int main(){ 33 FindMiniSteps(13); 34 FindMiniSteps(10); 35 system("pause"); 36 return 0; 37 }
Found number n at level 5
Found number n at level 4
越努力,越幸运