01 如何尋找數組中的最小值與最大值
static int Max;
static int Min;
public static void getMaxAndMin(int arr[]){
Max =arr[0];
Min =arr[0];
int len =arr.length;
for (int i=0;i<len-1;i=i+2){
if (i+1>len){
if (arr[i]>Max)
Max =arr[i];
if (arr[i]<Min)
Min =arr[i];
}
if (arr[i]>arr[i+1]){
if (arr[i]>Max)
Max=arr[i];
else if (arr[i+1]<Min)
Min=arr[i+1];
}
if (arr[i]<arr[i+1]){
if (arr[i+1]>Max)
Max=arr[i+1];
else if (arr[i]<Min)
Min=arr[i];
}
}
}
public static void main(String[] args) {
int[] array={7,9,1,5,0,6,4,3};
getMaxAndMin(array);
System.out.println("Max = "+Max);
System.out.println("Min = "+Min);
}
02 如何找出數組中的第二大的數
先定義兩個變量,一個變量用來存儲數組的最大值,另一個存儲數組第二大的值。遍歷數組如果數組元素比最大值大。第二大的值更新爲之前最大值,最大值也更新。如果比最大值小,比較第二大的值。如果比第二大的值大。更新第二大的值。
public static int findSecMax(int arr[]){
int max=arr[0];
int secMax=Integer.MIN_VALUE;
for (int i=1;i<arr.length;i++){
if (arr[i]>max){
secMax=max;
max=arr[i];
}else{
if (arr[i]>secMax){
secMax=arr[i];
}
}
}
return secMax;
}
public static void main(String[] args) {
int[] array={7,9,1,5,0,6,4,3};
System.out.println(findSecMax(array));
}
03 如果求最大子數組之和
方法一:蠻力法
找出所有子數組,然後求出子數組的和。在所有子數組的和中取最大值。
public static int getMaxSubArray(int arr[]){
int MaxSub=0;
for (int i=0;i<arr.length;i++){
for (int j=i;j<arr.length;j++){
int ThisSub=0;
for (int k=i;k<j;k++){
ThisSub+=arr[k];
}
if (ThisSub>MaxSub){
MaxSub=ThisSub;
}
}
}
return MaxSub;
}
public static void main(String[] args) {
int[] array={7,-9,1,-10,0,-12,4,10,3,12};
System.out.println(getMaxSubArray(array));
}
方法二:重複利用已經計算的子數組和
例如:sum[ i , j ] = sum[ i , j - 1 ] + arr[ j ] ,採用這種方法可以省去計算sum[i , j - 1 ]的時間。
public static int getMaxSubArray1(int arr[]){
int maxSub=0;
for(int i=0;i<arr.length;i++){
int sum=0;
for (int j=i;j<arr.length;j++){
sum+=arr[j];
if (maxSub<sum)
maxSub=sum;
}
}
return maxSub;
}
public static void main(String[] args) {
int[] array={7,-9,1,-10,0,-12,4,10,3,12};
System.out.println(getMaxSubArray1(array));
}
方法三:動態規劃方法
public static int max(int m,int n){
return m>n?m:n;
}
public static int getMaxSubArray2(int arr[]){
int n=arr.length;
int End[]=new int[n];
int All[]=new int[n];
End[n-1]=arr[n-1];
All[n-1]=All[n-1];
End[0]=All[0]=arr[0];
for (int i=1;i<n;i++){
End[i]=max(End[i-1]+arr[i],arr[i]);
All[i]=max(End[i],All[i-1]);
}
return All[n-1];
}
public static void main(String[] args) {
int[] array={7,-9,1,-10,0,-12,4,10,3,12};
System.out.println(getMaxSubArray2(array));
}
方法四:優化動態規劃
方法三中每次只用End[ i-1 ] 與 All[ i- 1 ] ,而不是整個數組中的值,因此可以定義兩個變量來保存End[ i - 1 ] 的值,並且反覆利用。
public static int max(int m,int n){
return m>n?m:n;
}
public static int getMaxSubArray3(int arr[]){
int n=arr.length;
int nAll=arr[0];//有n個數字數組的最大子數組和
int nEnd=arr[0];//有n個數字數組包含最後一個元素的子數組的最大和
for (int i=1;i<n;i++){
nEnd=max(nEnd+arr[i],arr[i]);
nAll=max(nEnd,nAll);
}
return nAll;
}
public static void main(String[] args) {
int[] array={7,-9,1,-10,0,-12,4,10,3,12};
System.out.println(getMaxSubArray3(array));
}
引申:在指導子數組中的最大和之後,如何才能確定最大子數組的位置呢?
private static int begin=0;//記錄最大子數組的起始位置
private static int end=0;//記錄最大子數組的結束位置
public static int getMaxSubArray(int []arr){
int maxSum=Integer.MIN_VALUE;//子數組最大值;
int nSum=0;//包含最後一位的最大值
int nStart=0;
for (int i=0;i<arr.length;i++){
if (nSum<0){
nSum=arr[i];
nStart=i;
}else {
nSum+=arr[i];
}
if (nSum>maxSum){
maxSum=nSum;
begin=nStart;
end=i;
}
}
return maxSum;
}
public static void main(String[] args) {
int[] array={7,-9,1,-100,0,-12,4,-100,3,12};
System.out.println(getMaxSubArray(array));
System.out.println("begin:"+array[begin]+" end:"+array[end]);
}
04 如何找出數組中重複元素最多的數
使用Map映射表,來紀律每一個元素出現的次數,然後判斷次數大小。
private static int result;
private static int val;
public static void findMostFrequentInArray(int arr[]){
Map<Integer,Integer> m=new HashMap<>();
for (int i=0;i<arr.length;i++){
if (m.containsKey(arr[i])){
m.put(arr[i],m.get(arr[i])+1);
}else {
m.put(arr[i],1);
}
}
//找出出現次數最多的元素
Iterator<Map.Entry<Integer, Integer>> iter = m.entrySet().iterator();
while (iter.hasNext()){
Map.Entry<Integer, Integer> entry = iter.next();
int key = entry.getKey();
int value = entry.getValue();
if (result<value){
result=value;
val=key;
}
}
}
public static void main(String[] args) {
int[] array={1,2,1,2,4,5,1,2,1,2,3,2,2,4,1,5};
findMostFrequentInArray(array);
System.out.println("數:"+val);
System.out.println("個數:"+result);
}
05 如何求數組中倆倆相加等於10的組合種數
方法一:蠻力法
採用雙重循環遍歷數組來判斷兩個數的和是否爲20
public static void findSum(int arr[],int sum){
int len = arr.length;
for (int i=0;i<len;i++){
for (int j=i+1;j<len;j++){
if (arr[i]+arr[j]==sum)
System.out.println("兩個數爲:"+arr[i]+" "+arr[j]);
}
}
}
public static void main(String[] args) {
int array[]={1,9,5,4,6,3,7,2,8,11,10};
findSum(array,10);
}
方法二:排序法
先對數組進行排序(快速排序或堆排序),然後對排序後的數組從前到後和從後到前遍歷,滿足arr[begin]+arr[end]<10 ,那就組合就在 arr[begin+1]+arr[end] 尋找,如果arr[begin]+arr[end]>10 ,就在 arr[begin]+arr[end - 1 ]尋找
public static void findSum1(int arr[],int sum){
Arrays.sort(arr);
int begin=0;
int end=arr.length-1;
while (begin<end){
if (arr[begin]+arr[end]<sum)
begin++;
else if (arr[begin]+arr[end]>sum)
end--;
else{
System.out.println("兩個數爲:"+arr[begin]+" "+arr[end]);
begin++;
end--;
}
}
}
public static void main(String[] args) {
int array[]={1,9,5,4,6,3,7,2,8,11,10};
findSum1(array,10);
}