
今年某公司面试题,题解如下:
public static boolean isTriangleNum(int n1,int n2,int n3){
if (n1 == n2 && n2 == n3) return false;//如果输入的3个数相同,则直接返回false
if (n1<1 || n2 <1 || n3 <1) return false;//如果输入的3个数中存在小于1的数,直接返回false
HashMap num_row = new HashMap<>(){//创建对应输入3个数的HashMap,默认value值设为0
private static final long serialVersionUID = -8162998925124303747L;
{
put(n1,0);
put(n2,0);
put(n3,0);
}
};
//取出3个数中的最大值 中间值 最小值
int[] nums = new int[]{n1,n2,n3};
Arrays.sort(nums);//将nums按从小到大的顺序排列
//确定3个数都在第几行
int pos = 1;//行数
int row_start_num = 1;//每一行的起始值
int row_end_num = 1;//每一行的结束值
while (true){
//判断n是否即小于等于当前行的行尾,又大于等于当前行的行首,如果是,则在HashMap中将当前n的value值置为当前行数
if (n1 <= row_end_num && n1 >= row_start_num){num_row.put(n1,pos);}
if (n2 <= row_end_num && n2 >= row_start_num){num_row.put(n2,pos);}
if (n3 <= row_end_num && n3 >= row_start_num){num_row.put(n3,pos);}
//判断HashMap中3个key是否都有了新的value值,即3个数是否都找到了自己的所在行,如果是,则结束while循环。
if (num_row.get(n1) !=0 && num_row.get(n2) !=0 && num_row.get(n3) !=0){break;}
row_start_num +=pos;//新行首 = 旧行首 + 旧行
pos++;//换下一行
row_end_num += row_start_num;//新行尾 = 旧行尾 + 新行
}
//取出最大值、中间值、最小值的行数
int max_row = num_row.get(nums[2]),mid_row = num_row.get(nums[1]),min_row = num_row.get(nums[0]);
//上三角形判断,如果 mid_num 和 max_num在同一行,则为上三角
if (max_row == mid_row){
int row_sumFromMax = 0;//从最大行所在行数向上一直加到最小行所在行数(不包括最小行) 等于 最大值-最小值
int row_sumFromMin = 0;//从最小行所在行数向下一直加到最大行所在行数(不包括最大行) 等于 中间值-最小值
for (int i = max_row;i>min_row;i--){row_sumFromMax += i;}
for (int i = min_row;imin_row;i--){row_sumFromMax += i;}
for (int i = min_row;i即3个数分布在3个行上,那肯定不是三角形数,直接返回false
}
}
实际测试可采用键盘录入3个数测试,也可以采用生成指定范围3个随机整数进行测试,测试代码不再赘述。