剣指Offerプログラミング整理(三)
13502 ワード
1、二叉探索木の後順遍歴シーケンス
2、二叉木とある値の経路
3、複雑なチェーンテーブルのコピー
4、二叉検索ツリーと双方向チェーンテーブル
5、文字列の配列
6、配列の出現回数が半分を超える数字
7、最小のk個数
8、連続サブ配列の最大和
9、整数のうち1の出現回数(1からnのうち1の出現回数)
10、配列を最小にする
11、ブス数
1、二叉探索木の後順遍歴シーケンス
(1)問題の説明:
整数配列を入力し、その配列が二叉探索ツリーの後順に遍歴した結果であるかどうかを判断します.もしそうであればYesを出力し、そうでなければNoを出力します.入力された配列の任意の2つの数字が互いに異なると仮定します.
(2)問題を解く構想:
二叉検索ツリー:すなわち、二叉ソートツリー、または空のツリー、または次の性質を持つ二叉ツリーです.左のサブツリーが空でない場合、左のサブツリー上のすべてのノードの値は、そのルートノードの値よりも小さくなります.その右に
サブツリーが空でない場合、右サブツリー上のすべてのノードの値は、そのルートノードの値よりも大きくなります.その左、右のサブツリーもそれぞれ二叉探索ツリーである.
後順遍歴:左右のルート;
以上から、配列の最後の要素はルートノードであることがわかる.
配列の前のn-1要素は2つの部分に分けることができ、左の値は右の値より小さい.
再帰的に左右の木が1本もないと判断した.
(3)コード実装:
補足:
Arrays.copyOfRange(T[]original,int from,int to)元の配列originalを、小標fromからコピーし、小標toにコピーし、下標fromを含む新しい配列を生成します.
下付きtoは含まれず,効率はcloneとほぼ一致し,いずれもnative methodであり,ループレプリケーション配列を利用するよりもはるかに効率的である.
2、二叉木とある値の経路
(1)問題の説明:
ツリーと整数を入力し、ツリー内のノード値と入力整数のすべてのパスを印刷します.パスは、ツリーのルートノードからリーフノードまで続くノードがパスを形成するように定義されます.
ツリーノードの定義:
(2)問題を解く構想:
深さは遍歴し,遍歴しながら累加する.
(3)コード実装:
(1)問題の説明:
複雑なチェーンテーブル(各ノードにノード値と2つのポインタがあり、1つは次のノードを指し、もう1つの特殊なポインタは任意のノードを指す)を入力し、コピー後の複雑なチェーンテーブルのheadを返します.(注)
なお、出力結果ではパラメータのノード参照を返さないでください.そうしないと、問題判定プログラムは直接空に戻ります)
(2)問題を解く構想:
法一:レプリケーションプロセスを2つのステップに分け、最初のステップは元のチェーンテーブルの各ノードをレプリケーションし、nextでリンクします.第2のステップでは、各ノードを位置決めするrandomは、チェーンテーブルのヘッダノードから開始する必要があります.
法2:空間を時間に変えて、最初のステップは元のチェーンテーブルの各ノードNをコピーしてN’を新しくして、それからこれらの新しくできたノードをnextでリンクします.同時にペアリング情報をハッシュテーブルに配置します.ステップ2
元のチェーンテーブルにおけるノードNのrandomポインタがSを指す場合、複製チェーンテーブルにおいて、対応するN’がS’を指す場合、ハッシュテーブルを用いてSに基づいてS’を見つけることができる.
法3:最初のステップは、元のチェーンテーブル上の各ノードNをコピーして、対応するN’を作成し、N’をNの後に置く.ステップ2:各ノードのrandomを設定する 針.元のチェーンテーブル上のノードNのrandomがSを指す場合、対応する複製ノードN’のrandomはS’を指す. 第三歩:長鎖表を二つの鎖表に分ける:奇数位置の結点をnextで接続すると元の鎖表であり、偶数位置の結点をnextで接続すると複製された鎖表である.
(3)コード実装:法三:
(1)問題の説明:
ツリーを入力し、ツリーを並べ替えた双方向チェーンテーブルに変換します.新しいノードを作成できない必要があります.ツリー内のノードポインタの方向を調整するしかありません.
(2)問題を解く構想:
左サブツリーを2つのチェーンテーブルに構築し、チェーンテーブルヘッダノードに戻ります.
左サブツリーの二重チェーンテーブルの最後のノードにナビゲートします.
左サブツリーチェーンテーブルが空でない場合は、現在のrootを左サブツリーチェーンテーブルに追加します.
右サブツリーを二重チェーンテーブルに作成し、チェーンテーブルヘッダノードに戻ります.
右サブツリーチェーンテーブルが空でない場合は、そのチェーンテーブルをrootノードの後に追加します.左サブツリーチェーンテーブルが空であるかどうかに基づいて、返されるノードを決定します.
(3)コード実装:
(1)問題の説明:
文字列を入力し、その文字列のすべての配列を辞書順に印刷します.例えば文字列abcを入力すると、文字a,b,cで並べられるすべての文字列abc,acb,bac,bca,cab,cbaが印刷される.
(2)問題を解く構想:
1番目の可能性のあるすべての状況をリストし、後のビットを再帰します.
1位と各位を交換する.再帰的な終了条件は、1番目と最後の交換が完了することである.
(3)コード実装:
6、配列の出現回数が半分を超える数字
(1)問題の説明:
配列の1つの数字が配列の長さの半分を超える回数がある場合は、この数字を見つけてください.例えば、長さ9の配列{1,2,3,2,2,5,4,2}を入力します.数字2は配列中に5回出現し,配列長の半分を超えるため,2を出力する.存在しない場合は0を出力します.
(2)問題を解く構想:
配列の数が配列の長さの半分を超える場合、並べ替え後、その数は配列の真ん中にあるに違いない.
まず速い列を行って、それから配列の最も中間の数を取ります;
この配列を巡って、最も中間の数が配列の長さの半分を超えると、この数が出力されます.
(3)コード実装:
7、最小のK個数
(1)問題の説明:
n個の整数を入力し、その中で最も小さいK個の数を見つけます.例えば4,5,1,6,2,7,3,8の8つの数字を入力すると、最小の4つの数字は1,2,3,4である.
(2)問題を解く構想:
法一:配列を速く並べます;早い列の後ろのK個の数を取る.
法二:配列の前のk個の数を1つのcopyを1つの配列int[]tempに置く.temp配列を速く並べます.元の配列のk番目の要素から始め、temp配列の中で最大の要素temp[k-1]と1つずつ比較する.temp[k-1]
元の配列より小さい場合は、元の配列を1つ取り外し、temp[k-1]が元の配列の要素より大きい場合は、2つの数を交換し、temp配列を速く並べます.最後にtemp配列を出力します.
(3)コード実装:
法一:略
法二:
(1)問題の説明:
HZはたまに専門的な問題を持って非コンピュータ専門の同級生をからかっている.今日のテストグループの会議が終わった後、彼はまた話をしました:古い1次元モードの識別の中で、いつも連続するサブベクトルの最大和を計算する必要があって、ベクトルがすべて正数の時、問題はとてもよく解決します.しかし、ベクトルに負の数が含まれている場合、ある負の数を含んで、隣の正の数が補うことを期待しますか?例えば,{6,−3,−2,7,−15,1,2,2},連続サブベクトルの最大和は8(0番目から3番目まで)である.彼にだまされるの?(サブベクトルの長さは少なくとも1)
(2)問題を解く構想:
法一:蛮力法、すべてのサブ配列を見つける;
法二:計算されたサブ配列の和を繰り返し利用する.
法三:動的計画:
currSumを現在の要素で終わる最大連続サブ配列の和にします.
maxSumはグローバルで最も大きなサブ配列の和である.
後でスキャンすると、j番目の要素には2つの選択があり、前に見つかったサブ配列を入れるか、最新のサブ配列の最初の要素を入れるかのいずれかです.
currSum>0の場合、currSumにa[j]を加算する.
currSum<0の場合、currSumは現在の要素として設定されます.すなわちcurrSum=a[j];
(3)コード実装:
法一:略
法二:
9、整数のうち1が現れる回数(1からnまでの整数のうち1が現れる回数)
(1)問題の説明:
1~13の整数のうち1が出現する回数を求め、100~1300の整数のうち1が出現する回数を算出する.そのため、1~13に含まれる1の数字を1、10、11、12、13と特別に数えて6回も現れたが、後の問題には仕方がない.ACMerはあなたたちが彼を助けることを望んで、そして問題をもっと普遍化して、すぐに任意の非負の整数区間の中で1の出現の回数を求めることができます.
(2)問題を解く構想:
法一:文字配列;
法二:数学の方法.
(3)コード実装:
法一:
法二:
10、配列を最小にする
(1)問題の説明:
正の整数配列を入力し、配列内のすべての数字をつなぎ合わせて1つの数に並べ、つなぎ合わせることができるすべての数字の中で最小の1つを印刷します.例えば配列{3,32321}を入力すると、この3つの数字が並べられる最小数字は321323となる.
(2)問題を解く構想:
「3」と「32」は直接「3」.compareTo(「32」)の演算を行うことができない.2つの文字列をつなぎ合わせて「332」.compareTo(「323」)を比較するのです
(3)コード実装:
11、ブス数
(1)問題の説明:
因子2,3,5のみを含む数をブス数(Ugly Number)と呼ぶ.例えば、6、8はすべて丑数であるが、14は因子7を含むためではない.習慣的に私たちは1を最初の醜数と見なしています.小さいから大きい順のN番目の丑数を求めます.
(2)問題を解く構想:
法一:各整数が丑数であるかどうかを逐一判断し、丑数の定義によると、丑数は2,3,5でしか除かれない.つまり、1つの数が2で割り切れると、私たちはそれを連続的に2で割ることができます.3で割り切れるなら、連続して3で割る.5で割り切れるなら、5で割る.もし最後に私たちが得たのが1であれば、この数は醜い数で、そうでなければそうではありません.
法二:配列を作成して見つかったブス数を保存し、空間で時間を変え、ブス数の定義によると、ブス数は別のブス数に2,3,5を乗じた結果、配列を作成し、中の数字はソートされたブス数であり、それぞれのブス数は前のブス数に2,3,5を乗じたものである.
(3)コード実装:
法一:略;
法二;
2、二叉木とある値の経路
3、複雑なチェーンテーブルのコピー
4、二叉検索ツリーと双方向チェーンテーブル
5、文字列の配列
6、配列の出現回数が半分を超える数字
7、最小のk個数
8、連続サブ配列の最大和
9、整数のうち1の出現回数(1からnのうち1の出現回数)
10、配列を最小にする
11、ブス数
1、二叉探索木の後順遍歴シーケンス
(1)問題の説明:
整数配列を入力し、その配列が二叉探索ツリーの後順に遍歴した結果であるかどうかを判断します.もしそうであればYesを出力し、そうでなければNoを出力します.入力された配列の任意の2つの数字が互いに異なると仮定します.
(2)問題を解く構想:
二叉検索ツリー:すなわち、二叉ソートツリー、または空のツリー、または次の性質を持つ二叉ツリーです.左のサブツリーが空でない場合、左のサブツリー上のすべてのノードの値は、そのルートノードの値よりも小さくなります.その右に
サブツリーが空でない場合、右サブツリー上のすべてのノードの値は、そのルートノードの値よりも大きくなります.その左、右のサブツリーもそれぞれ二叉探索ツリーである.
後順遍歴:左右のルート;
以上から、配列の最後の要素はルートノードであることがわかる.
配列の前のn-1要素は2つの部分に分けることができ、左の値は右の値より小さい.
再帰的に左右の木が1本もないと判断した.
(3)コード実装:
public boolean VerifySquenceOfBST(int [] sequence) {
if(sequence==null||sequence.length==0)
return false;
boolean res=getRes(sequence,0,sequence.length-1);
return res;
}
public boolean getRes(int[] s,int start,int end){
int i=0;
int j=0;
if(end-start<=1)
return true;
for(i=start;is[end])
break;
}
for(j=i;j0){
left=getRes(s,start,i-1);
}
if(i
補足:
Arrays.copyOfRange(T[]original,int from,int to)元の配列originalを、小標fromからコピーし、小標toにコピーし、下標fromを含む新しい配列を生成します.
下付きtoは含まれず,効率はcloneとほぼ一致し,いずれもnative methodであり,ループレプリケーション配列を利用するよりもはるかに効率的である.
2、二叉木とある値の経路
(1)問題の説明:
ツリーと整数を入力し、ツリー内のノード値と入力整数のすべてのパスを印刷します.パスは、ツリーのルートノードからリーフノードまで続くノードがパスを形成するように定義されます.
ツリーノードの定義:
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
(2)問題を解く構想:
深さは遍歴し,遍歴しながら累加する.
(3)コード実装:
public class Solution {
ArrayList> result=new ArrayList>();
ArrayList arr=new ArrayList();
int num=0;
public ArrayList> FindPath(TreeNode root,int target) {
if(root==null)
return result;
boolean isLeaf=root.left==null&&root.right==null;
num+=root.val;
arr.add(root.val);
if(num==target&&isLeaf){
ArrayList path=new ArrayList();
for(int i=0;i
3、複雑なチェーンテーブルのコピー(1)問題の説明:
複雑なチェーンテーブル(各ノードにノード値と2つのポインタがあり、1つは次のノードを指し、もう1つの特殊なポインタは任意のノードを指す)を入力し、コピー後の複雑なチェーンテーブルのheadを返します.(注)
なお、出力結果ではパラメータのノード参照を返さないでください.そうしないと、問題判定プログラムは直接空に戻ります)
(2)問題を解く構想:
法一:レプリケーションプロセスを2つのステップに分け、最初のステップは元のチェーンテーブルの各ノードをレプリケーションし、nextでリンクします.第2のステップでは、各ノードを位置決めするrandomは、チェーンテーブルのヘッダノードから開始する必要があります.
法2:空間を時間に変えて、最初のステップは元のチェーンテーブルの各ノードNをコピーしてN’を新しくして、それからこれらの新しくできたノードをnextでリンクします.同時にペアリング情報をハッシュテーブルに配置します.ステップ2
元のチェーンテーブルにおけるノードNのrandomポインタがSを指す場合、複製チェーンテーブルにおいて、対応するN’がS’を指す場合、ハッシュテーブルを用いてSに基づいてS’を見つけることができる.
法3:最初のステップは、元のチェーンテーブル上の各ノードNをコピーして、対応するN’を作成し、N’をNの後に置く.ステップ2:各ノードのrandomを設定する 針.元のチェーンテーブル上のノードNのrandomがSを指す場合、対応する複製ノードN’のrandomはS’を指す. 第三歩:長鎖表を二つの鎖表に分ける:奇数位置の結点をnextで接続すると元の鎖表であり、偶数位置の結点をnextで接続すると複製された鎖表である.
(3)コード実装:法三:
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
if(pHead==null)
return null;
RandomListNode pCur=pHead;
while(pCur!=null){
RandomListNode node=new RandomListNode(pCur.label);
node.next=pCur.next;
pCur.next=node;
pCur=node.next;
}
pCur=pHead;
while(pCur!=null){
if(pCur.random!=null)
pCur.next.random=pCur.random.next;
pCur=pCur.next.next;
}
RandomListNode head=pHead.next;
RandomListNode cur=head;
pCur=pHead;
while(pCur!=null){
pCur.next=pCur.next.next;
if(cur.next!=null)
cur.next=cur.next.next;
cur=cur.next;
pCur=pCur.next;
}
return head;
}
}
4、二叉検索ツリーと双方向チェーンテーブル(1)問題の説明:
ツリーを入力し、ツリーを並べ替えた双方向チェーンテーブルに変換します.新しいノードを作成できない必要があります.ツリー内のノードポインタの方向を調整するしかありません.
(2)問題を解く構想:
左サブツリーを2つのチェーンテーブルに構築し、チェーンテーブルヘッダノードに戻ります.
左サブツリーの二重チェーンテーブルの最後のノードにナビゲートします.
左サブツリーチェーンテーブルが空でない場合は、現在のrootを左サブツリーチェーンテーブルに追加します.
右サブツリーを二重チェーンテーブルに作成し、チェーンテーブルヘッダノードに戻ります.
右サブツリーチェーンテーブルが空でない場合は、そのチェーンテーブルをrootノードの後に追加します.左サブツリーチェーンテーブルが空であるかどうかに基づいて、返されるノードを決定します.
(3)コード実装:
public TreeNode Convert(TreeNode root) {
if(root==null)
return null;
if(root.left==null&&root.right==null)
return root;
// 1. ,
TreeNode left = Convert(root.left);
TreeNode p = left;
// 2.
while(p!=null&&p.right!=null){
p = p.right;
}
// 3. , root
if(left!=null){
p.right = root;
root.left = p;
}
// 4. ,
TreeNode right = Convert(root.right);
// 5. , root
if(right!=null){
right.left = root;
root.right = right;
}
return left!=null?left:root;
}
5、文字列の配列(1)問題の説明:
文字列を入力し、その文字列のすべての配列を辞書順に印刷します.例えば文字列abcを入力すると、文字a,b,cで並べられるすべての文字列abc,acb,bac,bca,cab,cbaが印刷される.
(2)問題を解く構想:
1番目の可能性のあるすべての状況をリストし、後のビットを再帰します.
1位と各位を交換する.再帰的な終了条件は、1番目と最後の交換が完了することである.
(3)コード実装:
import java.util.ArrayList;
import java.util.Collections;
public class Solution
{
public ArrayList Permutation(String str)
{
ArrayList res=new ArrayList();
if(str.length()==0||str==null)return res;
int n= str.length();
helper(res,0,str.toCharArray());
Collections.sort(res);// , , sort
return res;
}
public void helper( ArrayList res,int index,char []s)
{
if(index==s.length-1)res.add(new String(s)); ,
for(int i=index;i//
{
if(i==index||s[index]!=s[i])// ,
{
swap(s,index,i);
helper(res,index+1,s); , , , 。
swap(s,index,i);// ,
}
}
}
public void swap(char[]t,int i,int j)
{
char c=t[i];
t[i]=t[j];
t[j]=c;
}
}
6、配列の出現回数が半分を超える数字
(1)問題の説明:
配列の1つの数字が配列の長さの半分を超える回数がある場合は、この数字を見つけてください.例えば、長さ9の配列{1,2,3,2,2,5,4,2}を入力します.数字2は配列中に5回出現し,配列長の半分を超えるため,2を出力する.存在しない場合は0を出力します.
(2)問題を解く構想:
配列の数が配列の長さの半分を超える場合、並べ替え後、その数は配列の真ん中にあるに違いない.
まず速い列を行って、それから配列の最も中間の数を取ります;
この配列を巡って、最も中間の数が配列の長さの半分を超えると、この数が出力されます.
(3)コード実装:
public int MoreThanHalfNum_Solution(int [] array) {
int len=array.length;
if(len<1){
return 0;
}
int count=0;
Arrays.sort(array);
int num=array[len/2];
for(int i=0;i
7、最小のK個数
(1)問題の説明:
n個の整数を入力し、その中で最も小さいK個の数を見つけます.例えば4,5,1,6,2,7,3,8の8つの数字を入力すると、最小の4つの数字は1,2,3,4である.
(2)問題を解く構想:
法一:配列を速く並べます;早い列の後ろのK個の数を取る.
法二:配列の前のk個の数を1つのcopyを1つの配列int[]tempに置く.temp配列を速く並べます.元の配列のk番目の要素から始め、temp配列の中で最大の要素temp[k-1]と1つずつ比較する.temp[k-1]
元の配列より小さい場合は、元の配列を1つ取り外し、temp[k-1]が元の配列の要素より大きい場合は、2つの数を交換し、temp配列を速く並べます.最後にtemp配列を出力します.
(3)コード実装:
法一:略
法二:
public static ArrayList getLastKnum(int[] input,int k){
ArrayList list = new ArrayList();
int[] temp = new int[k];
temp = Arrays.copyOfRange(input,0,k);
Arrays.sort(temp);
for (int i = k ;i input[i]){
int a = temp[k-1];
temp[k-1] = input[i];
input[i] = a;
Arrays.sort(temp);
}
}
for (int i : temp){
list.add(i);
}
return list;
}
8、連続サブ配列の最大和(1)問題の説明:
HZはたまに専門的な問題を持って非コンピュータ専門の同級生をからかっている.今日のテストグループの会議が終わった後、彼はまた話をしました:古い1次元モードの識別の中で、いつも連続するサブベクトルの最大和を計算する必要があって、ベクトルがすべて正数の時、問題はとてもよく解決します.しかし、ベクトルに負の数が含まれている場合、ある負の数を含んで、隣の正の数が補うことを期待しますか?例えば,{6,−3,−2,7,−15,1,2,2},連続サブベクトルの最大和は8(0番目から3番目まで)である.彼にだまされるの?(サブベクトルの長さは少なくとも1)
(2)問題を解く構想:
法一:蛮力法、すべてのサブ配列を見つける;
法二:計算されたサブ配列の和を繰り返し利用する.
法三:動的計画:
currSumを現在の要素で終わる最大連続サブ配列の和にします.
maxSumはグローバルで最も大きなサブ配列の和である.
後でスキャンすると、j番目の要素には2つの選択があり、前に見つかったサブ配列を入れるか、最新のサブ配列の最初の要素を入れるかのいずれかです.
currSum>0の場合、currSumにa[j]を加算する.
currSum<0の場合、currSumは現在の要素として設定されます.すなわちcurrSum=a[j];
(3)コード実装:
法一:略
法二:
public int FindGreatestSumOfSubArray(int[] array) {
int max=array[0];
for(int i=0;imax)
max=sum;
}
}
return max;
}
法3:public static int FindGreatestSumOfSubArray(int[] array) {
if (array.length == 0 ){
return 0;
}
int currSum = 0;
int maxSum = array[0];
for (int j=0 ;j= 0){
currSum += array[j];
}else {
currSum = array[j];
}
if (currSum > maxSum){
maxSum = currSum;
}
}
return maxSum;
}
9、整数のうち1が現れる回数(1からnまでの整数のうち1が現れる回数)
(1)問題の説明:
1~13の整数のうち1が出現する回数を求め、100~1300の整数のうち1が出現する回数を算出する.そのため、1~13に含まれる1の数字を1、10、11、12、13と特別に数えて6回も現れたが、後の問題には仕方がない.ACMerはあなたたちが彼を助けることを望んで、そして問題をもっと普遍化して、すぐに任意の非負の整数区間の中で1の出現の回数を求めることができます.
(2)問題を解く構想:
法一:文字配列;
法二:数学の方法.
(3)コード実装:
法一:
public int NumberOf1Between1AndN_Solution(int n) {
int count=0;
while(n>0){
String str=String.valueOf(n);
char[] chars=str.toCharArray();
for(int i=0;i
法二:
public static int NumberOf1Between1AndN_Solution(int n) {
int count = 0;
for (long m = 1; m <= n; m *= 10)
count += (n/m + 8) / 10 * m + (n/m % 10 == 1 ? n%m + 1 : 0);
return count;
}
10、配列を最小にする
(1)問題の説明:
正の整数配列を入力し、配列内のすべての数字をつなぎ合わせて1つの数に並べ、つなぎ合わせることができるすべての数字の中で最小の1つを印刷します.例えば配列{3,32321}を入力すると、この3つの数字が並べられる最小数字は321323となる.
(2)問題を解く構想:
「3」と「32」は直接「3」.compareTo(「32」)の演算を行うことができない.2つの文字列をつなぎ合わせて「332」.compareTo(「323」)を比較するのです
(3)コード実装:
public String PrintMinNumber(int [] numbers) {
if(numbers==null||numbers.length==0)
return "";
int len=numbers.length;
String[] str=new String[len];
StringBuilder sb=new StringBuilder();
for(int i=0;i(){
public int compare(String s1,String s2){
String c1=s1+s2;
String c2=s2+s1;
return c1.compareTo(c2);
}
});
for(int i=0;i
11、ブス数
(1)問題の説明:
因子2,3,5のみを含む数をブス数(Ugly Number)と呼ぶ.例えば、6、8はすべて丑数であるが、14は因子7を含むためではない.習慣的に私たちは1を最初の醜数と見なしています.小さいから大きい順のN番目の丑数を求めます.
(2)問題を解く構想:
法一:各整数が丑数であるかどうかを逐一判断し、丑数の定義によると、丑数は2,3,5でしか除かれない.つまり、1つの数が2で割り切れると、私たちはそれを連続的に2で割ることができます.3で割り切れるなら、連続して3で割る.5で割り切れるなら、5で割る.もし最後に私たちが得たのが1であれば、この数は醜い数で、そうでなければそうではありません.
法二:配列を作成して見つかったブス数を保存し、空間で時間を変え、ブス数の定義によると、ブス数は別のブス数に2,3,5を乗じた結果、配列を作成し、中の数字はソートされたブス数であり、それぞれのブス数は前のブス数に2,3,5を乗じたものである.
(3)コード実装:
法一:略;
法二;
public int GetUglyNumber_Solution(int index) {
if(index<=0)
return 0;
int[] result=new int[index];
int count=0;
int i2=0;
int i3=0;
int i5=0;
result[0]=1;
int tmp=0;
while(countb)?b:a;
}