关于数组的常见算法题(随时更新)

一、求出数组中的第二大的元素
方法一:
先将数据排序好(快速排序),然后根据下标寻找第二大的元素
注意事项:
(1)如果元素都是同一个数,那么没有第二大
(2)最大的可能不止一个,所以不能直接输出arr[len-2],也要进行判断

public class FindSecondMax {
	 public static void quickSelect(int[] arr,int start,int end)
	{
		int len=arr.length;
		int i=start;
		int j=end;
		if(start>=end)
		{
			return;
		}
		int temp=arr[start];
		while(i<j)
		{
			while(i<j && arr[j]>=temp)
				j--;
			if(i<j)
				arr[i++]=arr[j];
			while(i<j && arr[i]<=temp)
				i++;
			if(i<j)
				arr[j--]=arr[i];
		}
		arr[i]=temp;
		quickSelect(arr,start,i-1);
		quickSelect(arr,i+1,end);
	}
	public static void main(String[] args) {
		int[] arr= {2,5,58,4,6,9,3,2,1,58,58};
		int len=arr.length;
		quickSelect(arr,0,len-1);
		//用于判断是不是元素值都一样
		int flag=0;
		for(int i=1;i<len;i++)
		{
			if(arr[i]!=arr[0])
			{
				flag=1;
				break;
			}
				
		}
		if(flag==0)
		{
			System.out.println("没有第二大");
			return;
		}
		//寻找第二大,因为最大的可能有好几个,并列的,所以不可以直接输
		//出倒数第二个下标的指
		int j=len-1;
		while(j>=1 && (arr[j-1]==arr[j]))
		{
			j--;
		}
		System.out.println("倒数第二小的值是" + arr[j-1]);
		
	}
	 

方法二:
可以定义两个变量,一个用来表示最大值,初始化可以是arr[0],一个用来表示第二大值,初始化是最小负整数。
然后遍历整个数组,
(1)如果元素比最大值大,那么把这个元素赋给最大值,把原先最大值付给第二大值
(2)如果元素等于最大值,什么都不做
(3)如果元素小于最大值,再判断是不是大于第二大,如果大于第二大,则把他赋给第二大

public static void main(String[] args)
	{
		int[] arr= {2,5,58,4,6,9,3,2,1,58,58};
		int len=arr.length;
		int max=arr[0];
		int sec_max=Integer.MIN_VALUE;
		for(int i=1;i<len;i++)
		{
			if(arr[i]>max)
			{
				sec_max=max;
				max=arr[i];
			}
			else if(arr[i]==max)
			{
				
			}
			else 
			{
				if(arr[i]>sec_max)
					sec_max=arr[i];
			}
		}
		System.out.println("第二大是:" + sec_max);
		
	}
	

二、求数组中两两相加等于20(这个数可以变)的组合数
方法一:
双重循环

public static void findSum(int[] ,int sum)
{
  int len=arr.length;
  for(int i=0;i<len;i++)
     for(int j=i;j<len;j++)
        if(arr[i]+arr[j]==sum)
           System.out.println(arr[i] + "," + arr[j]);
}

方法二
1、先排序(快速排序)
2、一个前后走,一个向前走。

package Arrays;

import java.util.Scanner;

public class DoubleAddFix {
	public static void quickSort(int[] arr,int start,int end)
	{
		int i=start;
		int j=end;
		if(start>=end)
		{
			return;
		}
		int temp=arr[start];
		while(i<j)
		{
			while(i<j && temp<=arr[j])
				j--;
			if(i<j)
				arr[i++]=arr[j];
			while(i<j && temp>=arr[i])
				i++;
			if(i<j)
				arr[j--]=arr[i];
		}
		arr[i]=temp;
		quickSort(arr,start,i-1);
		quickSort(arr,i+1,end);
	}
	 public static void doubleAddFix(int[] arr,int start,int end,int sum)
	 {
		 int flag=0;
		 int i=start;
		 int j=end;
		 while(i<j)
		 {
			 if(arr[i]+arr[j]<sum)
				 i++;
			 else if(arr[i]+arr[j]>sum)
				 j--;
			 else
			 {
				 flag=1;
				 System.out.println(arr[i] + "," +arr[j]);
				 i++;
				 j--;
			 }
		 }
		 if(flag==0)
		 {
			 System.out.println("没有符合条件的两个值");
			 return ;
		 }
	 }
	 
	 public static void main(String[] args) {
		int sum=20;
		Scanner sc=new Scanner(System.in);
		int N=sc.nextInt();
		int[] arr=new int[N];
		for(int i=0;i<N;i++)
		{
			arr[i]=sc.nextInt();
		}
		sc.close();
		quickSort(arr,0,N-1);
		doubleAddFix(arr,0,N-1,sum);
	}

}

三、如何把一个数组右移k位
思路:
例如:12345678右移2位结果是78123456
可以看出有两部分是和未移动前是一样的(123456)(78)所以把这两部分单独来看
算法思路:现把两部分单独逆序(65432187),然后总体逆序。(78123456)
左移同样适用
12345678左移3位
两部分单独逆序(32187654)整体逆序(45678123)

package Arrays;

import java.lang.reflect.Array;
import java.util.Arrays;

public class RightKPosition {
	//将数组的指定位置进行逆序
	public static void reverse(int[] arr,int start,int end)
	{
		int i=start;
		int j=end;
		int temp;
		while(i<j)
		{
			temp=arr[i];
			arr[i]=arr[j];
			arr[j]=temp;
			i++;
			j--;
		}
	}
	public static void rightKPosition(int[] arr,int k)
	{
		int len=arr.length;
		k=k%len;//防止k>len,右移k位和右移k%len位的结果一样
		reverse(arr,0,len-k-1);
		reverse(arr,len-k,len-1);
		reverse(arr,0,len-1);
		
	}
	public static void main(String[] args) {
		int[] arr= {1,2,3,4,5,6,7,8};
		rightKPosition(arr,0);
		System.out.println(Arrays.toString(arr));
	}

}

你可能感兴趣的:(技术)