1. 程式人生 > >LeetCode Happy Number 題解

LeetCode Happy Number 題解

先說一下題目

Write an algorithm to determine if a number is "happy".

A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.

Example: 19 is a happy number

  • 12 + 92 = 82
  • 82 + 22 = 68
  • 62 + 82 = 100
  • 12 + 02 + 02 = 1
  • 大致翻譯一下,題目要求判斷一個數是否是happy number ,判斷條件是將一個數十進位制各個位上的數平方和相加,如果和為1則是,和不為1且出現迴圈的就判為不是。

題目給的標籤是hashtable,這道題也很明顯應該用hashtable概念求解,首先是獲得一個數各位的平方和,這個很簡單,直接上程式碼

int getSum(int n)
{
	int sum = 0;// 各位平方總和
	int temp = 0;// 每一位上的和
	while (n)
	{
		temp = n % 10;
		sum += temp * temp;
		n /= 10;
	}
	return sum;
}
下面就是判斷是獲得的各個數的平方和中是否有重疊的數了,可以使用stl提供的map,unordered_map等,筆者下面用unordered_map實現一下,很簡單

bool isHappy(int n) {

	int sum = getSum(n);
	unordered_map<int,int>map;
	map.insert({ sum, 1 });

	while (sum)
	{
		sum = getSum(sum);
		if (sum == 1)
			return true;
		else
		{
			if (map.find(sum) !=  map.end())
			{
				// exits this number already
				return false;
			}
			else{
				// put it in map
				map.insert({ sum, 1 });
			}
		}
	}

	// sum becomes 0 so that there must be a circle
	return false;


}


在OJ上的執行時間是12ms,那麼還有沒有優化空間呢,完全有的。因為使用stl提供的unordered_map雖然效率夠高,但是為每一個數計算hash值顯然是多餘的。我們可以考慮自己實現hashtable。按照題意,只要各位數平方和出現了重複,就判定為非happy number,而各位數的平方和顯然最大值是可求的,為199999999的各位平方和730,所以以730為最大值建立hashtable要節省空間和時間,下面直接看程式碼

bool  isHappy(int n) {

	int sum = getSum(n);
	if (sum == 1)
		return true;
	// 最大平方和為1999999999的平方和
	bool table[731] = { 0 };
	table[sum] = 1;
	while (sum)
	{
		sum = getSum(sum);
		if (sum == 1)
			return true;
		else
		{
			if (table[sum])
			{
				// exits this number already
				return false;
			}
			else{
				// put it in map
				table[sum] = true;
			}
		}
	}
	return false;
}


這樣就大幅提升了效率,OJ上的執行時間為6ms。