1、二分查找法
二分查找数组中带有方法Arrays.binarySearch(数组,key);查到了返回第一个下标,查不到返回负数
该负数为应在数组中的位置+1取反;
二分查找法基本思想是基于已经排好序的数组(假设为升序),找到中间的那个数与被查找数对比,若比中间的数大,则往右再取中间,若小吗,往左取中间值再对比…
以下为手写原码:
package week02.day08.test;
public class BinarySearch {
public static void main(String[] args) {
int[] nums = {1,2,9,11,13};
int need = 3;
int index = binarySearch(need,nums);
System.out.println("该数在数组中"+index+"位置");
}
public static int binarySearch(int need,int[] nums) {
int mid ;
int startIndex = 0;
int endIndex = nums.length-1;
while(startIndex<=endIndex) {
mid = (startIndex+endIndex)/2;
if(need>nums[mid]) { //如果查找的该数大于截取数组的下标中间值
startIndex = mid +1;//在后半段去找,重新定义开始序号,
//(不管数组个数是奇数个还是偶数个,都会取到一半或一半前的一个,比如数组长度为10,此时mid取值为4
//mid已经大于下标为4的数了,所以下一次开始start取值为9/2+1=5,
}else if(need<nums[mid]) {//前半段找
endIndex = mid -1;//已经小于下标为4的数了,所以从3开始查找
}else {
return mid;
}
}
return -1;//没取到
}
}
2、数组的扩容
数组扩容带方法:nums = Arrays.copyOf(数组,新长度),把放进去的数组扩容,结果以返回值的形式给你
同理,缩容即是数组长度-1;
由于数组长度是不可改变的,扩容、缩容都是开辟新的数组空间重新赋值完成;
扩容思想就是把原数组已有数据复制给新的数组,并选定自己需要扩大的长度;
下面为数组扩容手写原码(已经封装为方法);
package week02.day08.test;
import java.util.Arrays;
public class DilatationArrays {
public static void main(String[] args) {
int[] nums = {1,3,4};
nums = dilatationArrays(nums);
System.out.println(Arrays.toString(nums));
}
//下面扩容两倍
public static int[] dilatationArrays(int[] nums) {
int[] newNums = new int[nums.length*2];
for(int i =0;i<nums.length;i++) {
newNums[i] = nums[i];
}
return newNums;
}
}
3、数组最值问题
这是一个方法,用于找到数组中第一个最大值下标位置。
先将数组第一个值定位最大值,然后遍历数组进行”打擂台“,赢了的赋值给max,代码部分如下:
//找到数组中第一个最大值出现位置的索引。
public static int getMaxIndex(int[] arrs) {
int max = arrs[0];//先取第一个值为最大值
int indexMax = 0;
for(int i=0;i<arrs.length;i++) {
if(max<arrs[i])//条件判断大的赋值为max存储
{
max=arrs[i];
indexMax = i;
}
}
return indexMax;
}
4、数组内第二大值查询
不考虑数组为空的情况下,给定一个整型数组,数组成员10个,求该数组中第二大的数的下标。
(若有多个第二大值,找到第一个下标即可)
1、要想得到某数组第二大数的下标,需先排除掉所有最大值(最大值可能不是一个);
2、遍历第二遍,排除最大值,起始比较需拿最小值进行比较,不能用数组的第一个数进行比较,因为数组第一个数可能是最大值;
3、当最大值和最小值相等时,代表该数组为里数值都相等的数组,无第二大值例如{1}{1,1,1,1};
package week02.day07.work;
public class Test {
public static void main(String[] args) {
int[] arr = { 8, 1, 911, 47, 75, 5 ,-10};
int secondMaxIndex = secondMaxIndex(arr);
System.out.println("最大值"+arr[getMaxIndex(arr)]);
System.out.println("最小值"+arr[getMinIndex(arr)]);
System.out.println("第二大值"+arr[secondMaxIndex]);
}
public static int secondMaxIndex(int[] arrs) {
int max = arrs[getMaxIndex(arrs)];//找到最大值
int min = arrs[getMinIndex(arrs)];//取最小值上擂台和除了最大值以外的数对比
if(min==max) {
return -1;
}//如果数组只有1个元素的情况........
int secondMaxIndex=getMinIndex(arrs);//先取最小值的索引为第二大值
for (int i = 0; i < arrs.length; i++) {
if (arrs[i] != max) {
if (arrs[i] > min) {
min = arrs[i];
secondMaxIndex=i;
}
}
}
return secondMaxIndex;
}
//找到数组中第一个最大值出现位置的索引。
public static int getMaxIndex(int[] arrs) {
int max = arrs[0];//先取第一个值为最大值
int indexMax = 0;
for(int i=0;i<arrs.length;i++) {
if(max<arrs[i])//条件判断大的赋值为max存储
{
max=arrs[i];
indexMax = i;
}
}
return indexMax;
}
public static int getMinIndex(int[] arrs) {
int min = arrs[0];
int indexMin = 0;
for(int i=0;i<arrs.length;i++) {
if(min>arrs[i]) {
min = arrs[i];
indexMin = i ;
}
}
return indexMin;
}
}
5、两个有序的数组,如何使用单层循环完成合并,且保证合并后有序。
首先我们知道数组的长度是无法改变的,要想获得一个两个数组之和的长度,一定需要定义第三个数组,然后前两个对比的数组,如何确定当前遍历到哪个数组哪个下标?我们定义三个变量,分别用于存储数组1当前的下标,数组2当前的下标及合并后的第三组数组下标;
每次从数组a拿出一个值和数组b拿出一个值进行比较,将对比得出的小的一个放入数组3,哪个数组取出的哪个数组下标+1;最后赋值给数组3,数组3下标+1;对比两个数组长度总和次数一定能够对比完成,某个数组循环完毕则退出循环。
package week02.day07.work;
import java.util.Arrays;
public class CombineOrderArrays {//合并有序数组
public static void main(String[] args) {
int[] nums1 = {1,2,5};
int[] nums2 = {2,3,8,9};
int a = 0,b=0,c=0;
int[] nums = new int[nums1.length+nums2.length];
for(int i=0;i<nums.length;i++) {
if(nums1[a]>nums2[b]) {
nums[c]=nums2[b];
b++;
}else {
nums[c]= nums1[a];
a++;
}
c++;
if(a==nums1.length||b==nums2.length) {//某一组数组对比完最后一个数后退出
break;
}
}
if(a<nums1.length) {//即表示数组1没读取完,接着a下标开始读取依次往后复制到数组3中
for(int i=a;i<nums1.length;i++) {
nums[c] = nums1 [i];
c++;//将从a开始的数组1赋值给从c开始的数组3,依次录入剩下的;
}
}else {
for(int i=b;i<nums2.length;i++) {//即表示数组2没读取完,接着b下标开始读取依次往后复制到数组3中
nums[c] = nums2 [i];
c++;
}
}
System.out.println(Arrays.toString(nums));
}
}
6、二维数组打印杨辉三角
二维数组,即数组里存放的是数组,把外层数组想成行,内层数组为每行的每个数;所以需要重新赋值每个内层数组里的长度,内层第一个数组,下标为0,长度为0+1=1;
杨辉三角一维为行,二维为列,从排列方式可以知道第i行存在i列;
由于数组
每一个下方数字是由肩上两个数字和,即为i行i列数值等于i-1行j-1列加上i-1行j列.
package week02.day08.work;
import java.util.Scanner;
public class yangHuiTriangle {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
System.out.println("输入你要打印的行数");
int num = scan.nextInt();
int[][] yangHui =new int[num][];
for(int i =0;i<yangHui.length;i++) {
yangHui[i] =new int[i+1];
//第i行数组长度为i+1,从第0行开始;
}
for(int i=0;i<num;i++) {//外层行数控制
for(int j=0;j<=i;j++) {//内层每行列数控制
if(j==0||j==yangHui[i].length-1) {
yangHui[i][j]=1;
}else {
yangHui[i][j] = yangHui[i-1][j-1]+yangHui[i-1][j];
}
System.out.print(yangHui[i][j]+"\t");
}
System.out.println();
}
for(int i = 0;i<yangHui.length;i++) {
for(int a=yangHui.length-i;a>0;a--) {
System.out.print("\t");
}
for(int j=0;j<yangHui[i].length;j++) {
System.out.print(yangHui[i][j]+"\t");
}
System.out.println();
}
}
}
7、数组的插入
数组插入的前提是一个有序数组,无序的插入直接在末尾加不就行了;
这里直接使用我们已知的方法 二分查找;找到该插入的位置,然后扩容,在该数后循环后移一位;
注意点:必须从数组末端开始后移,不然会将数据覆盖;
package week02.day08.test;
import java.util.Arrays;
import java.util.Scanner;
public class TestAdd {
public static void main(String[] args) {
int[] nums= {1,3,5,6,7,10,18};
Scanner scan = new Scanner(System.in);
System.out.println("输入一位数,插入数组");
int num = scan.nextInt();
int index = Arrays.binarySearch(nums, num);//使用二分查找找到该数在数组中什么位置
index = index>=0?index:-(index+1);//负数表示没有这个数,返回的也就是-(应该在的位置+1)
nums = Arrays.copyOf(nums, nums.length+1);//扩容一位
for(int i=nums.length-1;i>index;i--) {
nums[i]=nums[i-1];
}//循环在插入数之后数进行后移
nums[index]=num;
System.out.println(Arrays.toString(nums));
}
}
8、数组的删除
数组删除也就是找到该数在数组中的位置,然后循环前移,再使用缩容办法去掉最后一位即可;
注意点:必须从插入端开始前移,不然会将数据覆盖;
package week02.day08.test;
import java.util.Arrays;
import java.util.Scanner;
public class TestDelete {
public static void main(String[] args) {
int[] nums= {1,3,5,6,6,7,10,18};
Scanner scan = new Scanner(System.in);
System.out.println("输入一位数,数组中删除");
int num = scan.nextInt();
int index = Arrays.binarySearch(nums, num);
if(index<0) {
System.out.println("无此数据");
return;
}
for(int i=index;i<nums.length-1;i++) {
nums[i]=nums[i+1];
}//扩容一位,循环前移前移从内往外
nums = Arrays.copyOf(nums, nums.length-1);//缩容一位
System.out.println(Arrays.toString(nums));
}
}