问题:《编程之美》,page170. 寻找数组中的第二小数
public class FindSecondMin {
/**
* @author:lilywangcn
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array=new int[]{12,34,54,43,23,11,10,9,9,10,9,10};
try{
System.out.println("min2 is " + array[merge(array,0,array.length-1)[1]]);
System.out.println("min2 is " +directCompare(array));
}catch(Exception e){
e.printStackTrace();
}
}
/*
* 算法设计:
init:min=min2=array[0];
case: array[i]<min=min2 min2=min, min=array[i]; result: min<min2
case: array[i]<min<min2 min2=min,min=array[i]; result:min<min2
case: min=min2<=array[i] min2=array[i]; result:min<=min2
case: min=array[i]<min2 min2=array[i]; result:min2=min
case: min<array[i]<min2 min2=array[i]; result:min<min2
case: min<min2=array[i] 不处理。 result: min<min2
case:min<min2<array[i] 不处理。 result: min<min2
*/
public static int directCompare(int[] array) throws Exception{
check(array);
int min2;
int min;
if(array[0]>array[1]){
min2=array[0];
min=array[1];
}else{
min2=array[1];
min=array[0];
}
for(int i=2; i<array.length;i++){
if(min>array[i]){
min2=min;
min=array[i];
}else { //min<=array[i]
if(min==min2){ //min=min2<=array[i]
min2=array[i];
}else{ //min<min2,min2>array[i]
if(min2>array[i]&&min!=array[i]){
min2=array[i];
}
}
}
}
return min2;
}
也如下分析:
已知有min<min2,min,min2,array[i]的有序排列结果有三种
(1)(array[i],min,min2);需要对(min,min2)进行: min2=min,min=array[i]可以得到。处理条件:array[i]<min
(2)(min,array[i],min2);需要对(min,min2)进行: min2=array[i]可以得到。处理条件:min<array[i]<min2或min=min2<array[i]
(3)(min,min2,array[i]),不需要对(min,min2)做任何处理。条件:以上条件的反面
因此for循环也可如下:
for(int i=2; i<array.length;i++){
if(min>array[i]){
min2=min;
min=array[i];
}
if((min<array[i]&&array[i]<min2) || (min==min2 && min2<array[i])){
min2=array[i];
}
}
/*
* 归并过程
* left:(a1,a2),right:(b1,b2)
* if(a1<a2<=b1<=b2) return left;
* if(b1<b2<=a1<=a2) return right;
* 否则最小,第二小值分布在两边。
* if(a1<b1) min=a1,min2=b1;
* if(a1>b1) min=b1,min2=a1;
* if(a1=b1) case: a2=b2 return left;
* case: a2>b2 return a1,b2;
* case: a2<b2 return a1,a2;
*/
public static int[] merge(int[] array,int start,int end) throws Exception{
check(array);
int[] mins=new int[2];
if(end-start==1){
if(array[start]>array[end])
{
mins[0]=end;
mins[1]=start;
}else{
mins[0]=start;
mins[1]=end;
}
return mins;
}
if(start==end){
mins[0]=mins[1]=start;
return mins;
}else{
int[] left=merge(array,start,(start+end)/2);
int[] right=merge(array,(start+end)/2+1,end);
if(array[left[1]]<=array[right[0]]&& array[left[0]]!=array[left[1]]) return left;
if(array[right[1]]<=array[left[0]]&& array[right[0]]!=array[right[1]]) return right;
if( array[left[0]]<array[right[0]]){
mins[0]=left[0];
mins[1]=right[0];
}else if(( array[left[0]]==array[right[0]])){
if(array[right[0]]==array[right[1]]) return left;
mins[0]=left[0];
if(array[left[1]]<array[right[1]]){
mins[1]=left[1];
}else{
mins[1]=right[1];
}
}else{
mins[0]=right[0];
mins[1]=left[0];
}
return mins;
}
}
public static void check(int[] array) throws Exception{
if(array.length==0 )
throw new Exception("error,the array is empty");
else
if(array.length==1) throw new Exception("error,the array size is one");
}
}
分享到:
相关推荐
### 分治算法求解数组中第二大的元素 #### 背景介绍 在计算机科学领域,寻找数组中的最大或次大元素是常见的问题之一。这类问题不仅有助于理解数据结构的基本概念,也是评估算法效率和复杂度的良好案例。本文将探讨...
2. 查找第二大、第三小等值: - 遍历法:在已排序数组中,找到最大值后,再遍历一次数组找到次大值。 - 优先队列(堆):使用最大堆结构,可以快速找到最大的k个元素。 三、排序算法的时间复杂度和稳定性 时间...
例如,排序算法中的快速排序就是典型的分治算法,它将数组分为较小和较大的两部分,分别排序后再合并。又如,整数划分问题,可以通过限制最大加数不超过`m`来实现分治,将问题`q(n, m)`拆分为`q(n, m-1)`和`q(n-m, m...
### MATLAB算法查找数组中第二大数 #### 一、问题背景及需求分析 在计算机科学领域,查找数组中的第二大数值是一个常见的编程任务。本篇文章将详细探讨三种不同的算法方法:顺序比较算法、空间换时间的改进算法...
在计算机科学中,分治法被广泛应用于排序算法(如快速排序)、查找算法(如二分查找)以及许多其他算法设计中。 #### 二、旋转数组问题背景 旋转数组通常是指将一个一维数组按照一定的规则进行旋转操作后得到的...
本篇内容旨在通过一个具体的实例——从键盘输入一组整数,并利用分治算法找出这组整数中的第二大数——来深入理解分治算法的设计思路及其应用方法。 #### 分治算法原理 分治算法通常包括三个步骤: 1. **分解**:...
**二分法(Binary Search)**,又称为折半搜索或二分查找,是一种在有序数组中查找特定元素的搜索算法。它的基本思想是利用分治策略,将问题规模不断减半,直到找到目标值或者确定目标不存在。二分法在计算机科学中...
- 第二行:`x`数组的`n`个数,用空格分隔; - 第三行:`y`数组的`n`个数,用空格分隔。 #### 解题思路 为了找到两个有序数组的中位数,可以采用分治法的思想。具体步骤如下: 1. **初始化**:读取输入数据,创建两...
在本题中,我们关注的是如何运用分治算法来找到一组数字中的最大值和最小值,以及如何找出第k个最小元素。这两个问题都可以通过分治思想进行有效解决。 首先,寻找最大值和最小值。传统的做法是遍历整个数组,但...
在本案例中,我们将讨论如何利用分治法在C++中找到数组中的最大值和最小值。 首先,让我们了解分治法的基本步骤: 1. **分解**:将原始问题分解为若干个规模较小、相互独立、与原问题形式相同的子问题。 2. **解决...
根据矩阵乘法的定义,只有当第一个矩阵的列数等于第二个矩阵的行数时,两个矩阵才能相乘,因此A和B可以相乘得到一个2x4的矩阵C。 矩阵乘法的运算规则如下: 对于矩阵C的每个元素C[i][j](i表示行,j表示列),其值...
分治算法是计算机科学中的一种重要算法思想,其核心是将一个难以直接解决的大问题分解成一些规模较小的相同问题,递归地解决这些子问题,然后再将子问题的解合并以得到原来问题的解。本部分介绍的信息学奥赛教程PPT...
分治算法是一种解决复杂问题的策略,其核心思想是将大问题划分成若干个小问题,递归地解决这些小问题,然后合并这些小问题的解以得到原来大问题的解。分治算法的基本步骤通常包括分解、解决、合并三个阶段。 在描述...
- **斯特林第二类数**:计算斯特林第二类数的分治算法可以高效地解决这一问题。 - **汉诺塔问题**:通过递归地将盘子从一个柱子移动到另一个柱子,每次移动一个盘子。 - **最近点对问题**:在二维平面上找到距离最近...
在本课程件中,将从多个方面对分治算法进行详细阐述,包括其基本概念、典型应用案例(如数组排序、快速排序、数组中选取Top K元素、寻找相邻点对问题),以及分治策略的具体实现和运行时间分析等。 首先,分治算法...
在算法设计实验中,有一道题目的要求是使用分治法(Divide and Conquer)来求解一个数组中的两个最大值与两个最小值。与蛮力法不同,分治法通过将问题分解成若干子问题来解决,这些子问题的规模比原问题小,并且具有...
将有两名最优秀的雇员每人得到其中的一块,排名第一的得到最重的那块,排名第二的雇员得到袋子中最轻的金块。假设有一个比较重量的仪器,我们希望用最少的比较次数找到最重和最轻的金块。 算法分析:这个问题可以...
- **遍历**:从数组的第二个元素开始,逐个与当前的最大值和次最大值进行比较。 - **更新逻辑**: - 如果当前元素大于最大值\( x \),则将\( x \)的值赋给\( y \),并将当前元素赋值给\( x \)。 - 如果当前元素...
2. **二分搜索**:在有序数组中通过比较中间元素的方式缩小查找范围,直至找到目标值。 3. **哈希表查找**:利用哈希表的特性快速定位目标元素。 综上所述,《C算法I-IV(第一卷:基础、数据结构、排序和搜索)(第...
### 快速排序求解数组第k小元素 #### 知识点概述 在计算机科学领域,快速排序是一种高效的排序算法,它采用分而治之的策略来对一个数组进行排序。快速排序的一个常见应用是查找数组中的第k小元素。这种需求在很多...