数値 n がハッピー ナンバーかどうかを判断するアルゴリズムを作成します。
「ハッピーナンバー」は次のように定義されています。
正の整数の場合、数値は毎回、各位置の数字の二乗の合計に置き換えられます。
次に、数が1になるまでこのプロセスを繰り返します。または、無限ループになる可能性がありますが、1未満になることはありません.
このプロセスの結果が 1 の場合、その数はハッピー ナンバーです。
n がハッピー ナンバーの場合は true を返し、そうでない場合は false を返します。
例 1:
入力: n = 19
出力: true
説明:
1 2 + 9 2 = 82
8 2 + 2 2 = 68
6 2 + 8 2 = 100
1 2 + 0 2 + 0 2 = 1
例 2:
入力: n = 2
出力: false
ヒント:
1 <= n <= 2 31 - 1
本当なので引用します。
最初に頭に浮かぶコードは次のとおりです。
アイデアは次のとおりです: 配列を使用して、その中にサイクルがあるかどうかをカウントします. 数値が 1 回表示される場合は、配列内の対応する値に 1 を追加します. 数値がハッピー ナンバーである場合、サイクルはありません。必ずサイクルに入ります。
そのため、配列 count に 1 より大きい数値があれば、ループに入ったということであり、ハッピーな数値ではなく、false を返します。
class Solution {
public:
bool isHappy(int n) {
int a[100001]={
0};
memset(a,0,sizeof(a));
int he=0,m=n;
while(1){
he=0;
while(m){
he+=((m%10)*(m%10));
m/=10;
}
if(he==1)
return true;
a[he]++;
if(a[he]>1) //如果一个数出现了不止一次,说明有循环,返回false就可以了
return false;
m=he;
}
return false;
}
};
私は最近ハッシュテーブルを学びました, そしてこの質問の分類はハッシュテーブルにあります. 最初のコードの a 配列はカウントに使用されるため, ハッシュテーブルもこのように使用できます.不可同じキー値があるので、計算したデータをキー値として毎回ハッシュテーブルに格納し、ハッシュテーブルで同じキー値を探します。ある場合はループに入る、そうでない場合はループに入るいいえ。
class Solution {
public:
bool isHappy(int n) {
unordered_map<int,int> hashtable;
hashtable.insert(make_pair(n,0));//将n本身存入哈希表中,也是需要判断的,value值是多少都没关系,根本用不到
int he=0;
while(1){
he=0;
while(n){
he+=((n%10)*(n%10));
n/=10;
}
if(he==1)
return true;
if(hashtable.find(he)!=hashtable.end())//如果找到了一个重复的,说明其中有循环,就不是快乐数
return false;
else//放入哈希表中为下一次判断准备
hashtable.insert(make_pair(he,0));
n=he;
}
return false;
}
};
コメントを読んだ後、それは正しいと思い、コードを少し単純化して、これらの数字のいずれかが表示される限り、数え続ける必要がないようにしました。
class Solution {
public:
bool isHappy(int n) {
int he=0;
while(1){
he=0;
while(n){
he+=((n%10)*(n%10));
n/=10;
}
if(he==1)
return true;
if(he==4||he==16||he==37||he==58||he==89||he==145||he==42||he==20)
return false;//特殊判断,如果不是快乐数一定会进入这个循环
n=he;
}
return false;
}
};
コメントを読んだ後、突然別のことがわかりました。つまり、質問には差の絶対値がk未満であると書かれていますが、差が負の場合はk未満でなければならず、kは0 以上の場合、差が正の数の場合は k 未満であり、負の数よりも小さい必要があるため、上記のコードは abs() 関数を追加せずに渡すことができます。