1.数组中第二(n)大的元素及索引
1.思路
首先,新建一个此数组的副本数组,我们再对这个副本数组排序,然后再从最大值开始向下查找元素。如果当前元素与下一个元素不同,表示当前元素是第几号大的元素的变量currentOrder就加1,两相邻元素相同currentOrder的值则不变。当currentOrder与表示要查找的排号第几的变量order(找第一大数order则为1,第二大数order则为2)相等时,则当前元素值为要查找的元素。再通过此元素值,到原数组中去遍历,依次遍历过程中的某一元素值等于这个查找的元素,即获得其索引,用break语句退出循环。
而实际问题比以上分析更复杂一些。一方面若数组有10个元素,其中有3个元素重复,输入条件是查找第9大数,而实际只有第8大的数而已(无第9大数),另一方面以分析思路无法查找出最小的数(只能找出前一大小级别的元素)。这两方面的BUG都可以通过求非重复元素(多次重复出现的元素只计一个)的个数以解决。
(2)实现代码
int[] nums ={12,9,10,9,9,12,9,12,9,10,4}; //原数组
System.out.println("目前整数数组中的各元素值分别是:"+Arrays.toString(nums));
int[] copyNums=Arrays.copyOf(nums,nums.length); //副本数组
Arrays.sort(copyNums); //副本数组从小到大排序
System.out.println("排序后的元素:"+Arrays.toString(copyNums));
int order=3; //表示要查找的排第几大数的变量(查找第一大数order则为1,第二大数order则为2)
int orderNum=0; //要查找要查找第几大数对应的元素值
int currentOrder=0; //表示当前元素是第几大的元素的变量
/**表示非重复元素的数量(多次重复出现的元素只计作一个)的变量
* 初始值必须为1,否则会少计数一个
* 可理解为任何数组至少有一个元素。
*/
int countsUniqueElement=1; //非重复元素的数量
for(int i=0 ; i < copyNums.length-1; i++){
if(copyNums[i] != copyNums[i+1]){
countsUniqueElement++; //相邻元素不同则加1
}
}
/*非重复元素的数量刚好等于要查找的排第几大数的变量
* 而副本数组双是从小至大排序的,副本中的第一个元素值
* 则为要查找要查找第几大数对应的元素值
*/
if(order == countsUniqueElement)
{
orderNum=copyNums[0];
/**
* 查找超出边界
*/
}else if(order > countsUniqueElement)
{
System.out.println("数组中最小只有第"+countsUniqueElement+"大数;没有第"+order+"大数。");
System.exit(0);
/**
* 一般情况下,要查找第order大的数,order小于非重复元素的数量
*/
}else if(order < countsUniqueElement)
{
for(int i=copyNums.length-1;i>0;i--)
{
if(copyNums[i] !=copyNums[i-1])
{
// 当前元素与下一个元素不同,表示当前元素是第几号大的元素的变量currentOrder就加1
currentOrder++;
if(currentOrder == order)
{
/* 当currentOrder与表示要查找的排号第几的变量order,
* 则当前元素值为要查找的元素,并退出循环。
*/
orderNum=copyNums[i];
break;
}
}
}
}
int indexOfOrder=-1; //第order大数的索引
/**在原数组中找出第order大数第一次出现的位置
**/
for(int i=0; i<nums.length ;i++){
if(orderNum == nums[i]){
indexOfOrder=i;
break;
}
}
System.out.println("此数组中第"+order+"大数是:"+orderNum+",其索引是:"+indexOfOrder);
2.删除数组中重复的元素
(1)思路
删除重复元素,需要将重复值放在一起,那么就也需要对数组排序。一个数组的长度不能改变,所以需要定义一个新的数组,将不重复的元素放在新数组中。
定义新数组就需要知道其长度,那么还需要行计算出原数组中的非重复元素的个数。这里当然也就会用到上一题的思路。
(2)实现代码
int[] nums = new int[]{34,25,45,34,13,87,94,21,25};
System.out.println("原始数组序列是:"+Arrays.toString(nums));
Arrays.sort(nums);
System.out.println("排序后数组序列:"+Arrays.toString(nums));
int countsUniqueElement=1; //重复值只保留一个时,元素的个数,初始值为1。
for(int i=0 ; i < nums.length-1; i++){
if(nums[i] != nums[i+1]){
countsUniqueElement++; //相邻元素不同,非重复元素个数就加1
}
}
int[] uniqueOfArray= new int[countsUniqueElement]; //定义新数组
int index=0; //定义新数组的索引
for(int i=0 ; i < nums.length-1; i++){
if(nums[i] == nums[i+1]){
if(i==0){
uniqueOfArray[index]=nums[i]; //不论首元素是否重复,都需要将其赋值给新数组
index++;
}
}else{
if(i==0){
uniqueOfArray[index]=nums[i]; //不论首元素是否重复,都需要将其赋值给新数组
index++;
}
uniqueOfArray[index]=nums[i+1]; //除了首元素外,需要判断当前元素与下一元素是否重复
index++;
}
}
System.out.println("无重复值的新数组是"+Arrays.toString(uniqueOfArray));
通过以上案例可以看出,首元素、尾元素在很多情况下都是特殊情况(有时不能遍历到尾元素,有时又要在初始条件的值上加1),为了程序的健壮性,我们需要单独考虑其特殊性。