1. 程式人生 > >C++ LeetCode 完全平方數

C++ LeetCode 完全平方數

題目要求:

給定正整數 n,找到若干個完全平方數(比如 1, 4, 9, 16, ...)使得它們的和等於 n。你需要讓組成和的完全平方數的個數最少。

示例 1:

輸入: n = 12
輸出: 3 
解釋: 12 = 4 + 4 + 4.

示例 2:

輸入: n = 13
輸出: 2
解釋: 13 = 4 + 9.

解題思路:

由於遍歷範圍為N,所以首先想象有1~N個點,將其構造為一個圖結構,若某兩點的距離為i(i = 1, 2, 3, 4...)的平方,則將其連線。使用單獨佇列,進行廣度優先遍歷。從N開始,通過將其與i^2相減,得到的值設為temp ,將其與步數記錄在佇列中;同時記錄訪問過的點,若temp減去i^2得到了訪問過的點,由於已經是從N到該點的最小步數,於是跳過不予更新;最終返回最後的步數。用文字描述有點抽象,可以用設一個值單步執行一下就明瞭了。

示例程式碼:

int numSquares(int n)
{
    queue<pair<int, int>> q;
		
	q.push(make_pair(n, 0)); // 將初始的 值與步數 入隊

	vector<bool> visited(n, false); //  訪問記錄 的儲存
		
	int num;

	int step;

	while (!q.empty())
	{
		num = q.front().first;

		step = q.front().second;

		q.pop(); // 一個節點此時已經遍歷了所有相鄰的節點,故出隊,進行下一個節點的遍歷

		int i = 1;

		while (num - i * i >= 0)  // 對每個節點所有可能相鄰的點進行遍歷,並更新步數
		{
			int temp = num - i * i;
				
			if (temp == 0)
			{
				step++;
				return step;
			}

			else if (!visited[temp - 1]) //訪問過的節點已經是最小步數 所以不更新
			{
				q.push(make_pair(temp, step + 1));
						
				visited[temp - 1] = true;
					
			}
			i++;
		}
			
	}
	return step;
}