【算法】-- 【尋找數組最小、大值,數組第二大數,最大子數組之和,最多重複的數,等於10的組合】

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);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章