java常见算法

冒泡排序

原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,这样一趟过去后,最大或最小的数字被交换到了最后一位,然后再从头开始进行两两比较交换,直到倒数第二位时结束
public void exeBubbleSort(int[] arr){
    //循环躺数
    for(int i=0;i<arr.length;i++){
        //从左往右循环比较相邻元素大小,大的换到右边
        for(int j=0;j<arr.length-i-1;j++){
            if(arr[j]>arr[j+1]){
                int temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
    }
}

快速排序

它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

    public void exeQuickSort(int arr[],int low,int high){
        //左侧起始下标
        int l=low;
        //右侧起始下标
        int h=high;
        //中间值
        int povit=arr[low];
        //一趟循环,指导左右侧下标相等
        while(l<h)
        {
            //从右向左,当前值不小于中间值时,h递减,直到当前值小于中间值或l==h
            while(l<h&&arr[h]>=povit)
            h--;
            //如果当前值小于中间值,交换左右侧数据
            if(l<h){
                int temp=arr[h];
                arr[h]=arr[l];
                arr[l]=temp;
                l++;
            }
            //从左向右,当前值不大于中间值时,l递增,直到当前值大于中间值或l==h
            while(l<h&&arr[l]<=povit)
            l++;
            //如果当前值大于中间值,交换左右侧数据
            if(l<h){
                int temp=arr[h];
                arr[h]=arr[l];
                arr[l]=temp;
                h--;
             }
         }
        for(int a:arr){
            System.out.print(a);
        }
        System.out.println();
        System.out.print("l="+(l+1)+"h="+(h+1)+"povit="+povit+"\n");
        //如果此次循环左侧有交换(即此次中间值不是最小值),将中间值以左作为新的排序区间
        if(l>low)exeQuickSort(arr,low,l-1);
        //如果此次循环右侧有交换(即此次中间值不是最大值),将中间值以右作为新的排序区间
        if(h<high)exeQuickSort(arr,l+1,high);
    }

二分法查找

//递归实现二分法查找
int BinarySearch(int[] a,int key,int low,int high)
 {
    if(low>high||key<a[low]||key>a[high])        //越界处理
    {
         return -1;
     }
     int middle=(low+high)/2;
     if(key==a[middle])
     {
         return middle;
     }
    if(middle==low||middle==high)
     {
         if(key==a[low])
          {
             return low;
          }
          if(key==a[high])
          {
              return high;
          }
          else
         {
              return -1;
          }
      }
      if(key<a[middle])
      {
          return BinarySearch(a,key,low,middle);
      }
      if(key>a[middle])
      {
          return BinarySearch(a,key,middle,high);
      }
      return -1;
  }

  //循环实现二分法查找
  int BinarySearchByCircle(int * a,int key,int high)
  {
      int low=0;
     int middle;
      while(high>=low)
      {
          middle=(high+low)/2;
          if(key==a[middle])
          {
              return middle;
          }
          if(key<a[middle])
          {
              high=middle-1;
          }
          if(key>a[middle])
          {
             low=middle+1;
          }
      }
     return -1;
 }

大数相加

它的基本思想是:由于数据较大难以存放为整数型,可以存放为字符串并模拟加减法的数学演算法进行每一位的依次计算过程

    public static String plus(String num1,String num2){
        //最终符号
        String sign="";
        String sign1="";
        String sign2="";
        //获取符号和绝对值
        char h1=num1.charAt(0);
        char h2=num2.charAt(0);
        String number1="";
        String number2="";

        if(h1=='-'||h1=='+'){
            number1=num1.substring(1);
            sign1=h1+"";
        }else{
            number1=num1;
            sign1="+";
        }
        if(h2=='-'||h2=='+'){
            number2=num2.substring(1);
            sign2=h2+"";
        }else{
            number2=num2;
            sign2="+";
        }
        //校验
        boolean isDig1 = number2.matches("[1-9][0-9]*");  
        boolean isDig2 = number1.matches("[1-9][0-9]*");  
        if(!isDig1||!isDig2){
             throw new NumberFormatException("输入的数据不是正确的格式的整数");
        }
        //第一个数是否大于第二个数的绝对值
        boolean larger;
        if(number1.length()!=number2.length()){
            larger = number1.length()-number2.length()>0 ? true : false;
        }else{
            larger = number1.compareTo(number2)>0 ? true : false;
        }

        //字符串转化为栈
        char[] numArr1=number1.toCharArray();
        char[] numArr2=number2.toCharArray();

        int addNum=0;
        Stack<Integer> stack1 = new Stack<Integer>(); 
        Stack<Integer> stack2 = new Stack<Integer>(); 
        for(int i=0;i<numArr1.length;i++){
            String temp=String.valueOf(numArr1[i]);
            stack1.push(Integer.parseInt(temp));
        }
        for(int i=0;i<numArr2.length;i++){
            String temp=String.valueOf(numArr2[i]);
            stack2.push(Integer.parseInt(temp));
        }
        //临时存放栈
        Stack<Integer> res=new Stack<Integer>();

        //同号
        if(sign1.equals(sign2)){
            while(!stack1.isEmpty()||!stack2.isEmpty()){
                Integer n1=0;
                Integer n2=0;
                if(!stack1.isEmpty()){
                    n1=stack1.pop();
                }
                if(!stack2.isEmpty()){
                    n2=stack2.pop();
                }
                Integer sum=n1+n2+addNum;
                addNum=sum/10;
                sum=sum%10;
                res.push(sum);
            }
            sign=sign1;
        }else{//异号
            while(!stack1.isEmpty()||!stack2.isEmpty()){
                Integer n1=0;
                Integer n2=0;
                if(!stack1.isEmpty()){
                    n1=stack1.pop();
                }
                if(!stack2.isEmpty()){
                    n2=stack2.pop();
                }
                if(!larger){
                    Integer temp=n1;
                    n1=n2;
                    n2=temp;
                }
                Integer sum1=n1-n2;

                if(sum1<0){
                    sum1+=10;
                    res.push(sum1+addNum);
                    addNum=-1;
                }else{
                    res.push(sum1+addNum);
                    addNum=0;
                }

            }
            if(larger){
                if(sign1.equals("+")){
                    sign="+";
                }else{
                    sign="-";
                }
            }else{
                if(sign2.equals("+")){
                    sign="+";
                }else{
                    sign="-";
                }
            }
        }
        //同号添加最终进位
        if(addNum>0){
            res.push(1);
        }
        //临时存放StringBuffer
        StringBuffer str=new StringBuffer();
        while(!res.isEmpty()){
            str.append(res.pop());
        }
        //异号结果初始值不能为0
        if(str.charAt(0)=='0'){
            str=str.replace(0, 1, "");
        }
        return sign+str.toString();
    }

连续子数组的最大和

题目描述:在一维数组中,求出连续子数组的最大和。如果数组中全是整数,那么最大和为所有元素之和,那么存在负数呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。

 public static int FindGreatestSumOfSubArray(int[] array) {
         if (array.length==0 || array==null) {
             return 0;
         }
        int currentSum = 0;     //存储当前连续n项的和
        int max = 0;            //存储连续子元素和的最大值
        for (int i = 0; i < array.length; i++) {
            //核心部分,好好理解.
            if(currentSum<=0){      //如过当前连续n项的和小于等于0,则没必要与后面的元素相加
                currentSum = array[i];      //currentSum重新赋值
            }else{
                currentSum += array[i];     //如果currentSum的值大于0,则继续与后面的元素相加,
            }
            if(currentSum>max){         //每次改变currentSum的值都有与max进行比较
                max = currentSum;       //如果currentSum的值大于max,则将currentSum的值赋值给max
            }
        }
        return max;
     }  

数组去重

题目描述:在一维数组中去除一些重复的元素,只保留唯一值的集合,如[1,3,4,2,1,3,1,5]–>[1,3,4,2,5]

      public int[] removeRepeat(int[] arr){
            //剩余的未重复的数组的长度
            int unRepeatLen=arr.length;
            //遍历未重复的数组元素
            for(int i=0;i<unRepeatLen;i++){
                //将后面的未遍历且非重复的数组元素逐一和当前外层元素比较
                for(int j=i+1;j<unRepeatLen;j++){
                    //党发现重复时,将内层元素和最后一个未重复的元素交换位置
                    if(arr[i]==arr[j]){
                        int temp=arr[j];
                        arr[j]=arr[unRepeatLen-1];
                        arr[unRepeatLen-1]=temp;
                        //未重复元素数目减一
                        unRepeatLen--;
                        //换过来的元素也可能是重复元素,需要再进行比较
                        j--;
                    }
                }
                for(int x:arr){
                    System.out.print(x+",");
                }
                System.out.println();

            }
            int[] res=new int[unRepeatLen];
            System.arraycopy(arr, 0, res, 0, unRepeatLen);  
            return res;
        }

单词倒排

题目描述:对字符串中的所有单词进行倒排,如:you are how–>how are you

 public static void reverseChars(char[] chars, int begin, int end) {
            while(end>begin){
              char c = chars[begin];
              chars[begin] = chars[end];
              chars[end] = c;
              begin++;
              end--;
            }
      }


      public String reverseWords(String words){
          StringBuffer res=new StringBuffer();
          char[] cs=words.toCharArray();
          reverseChars(cs,0,cs.length-1);
          int begain=0;
          int end=0;
          for(int i=0;i<cs.length;i++){
              char c=cs[i];
              //当前需要倒排的单词是否还连续
              if((c>='a'&&c<='z')||(c>='A'&&c<='Z')||c=='\''){
                  //如果依然连续,需要同步单词结束下标                 
                 end=i;
                 if(i==cs.length-1){
                     if(end>begain){
                          reverseChars(cs,begain,end); 
                      }
                 }
              }else{
                  //如果不再连续,说明单词走到尽头,将之前的单词进行倒排
                  if(end>begain){
                      reverseChars(cs,begain,end); 
                  }
                  begain=i+1;
                  //end=i+1;
              }
          }
         return new String(cs);

      }

获取峰值

题目描述:当计算访问峰值时,我们说的的是一段时间内(比如4秒)的最大出现的最大访问次数。如[1,3,5,5,6,7,8,8,10,16]–>6

 public int getLargestTimesWithinRange(int[] arr,int range){
          int large=0;
          int start=0;
          for(int i=0;i<arr.length;i++){            
              //结束值和起始值的时间差在规定范围内,起始值不变;否则,起始值加1
              if(arr[i]-arr[start]>range){              
                  start++;
              }
              //范围内出现次数
              int temp=i-start+1;
              if(temp>large){
                  large=temp;
              }       
          }       
          return large;       
      }

连续整数缺失

题目描述:一段起始为start的本来连续的length个整数缺失了其中几个。如[1,2,4,5,6,7,8,10]–[3,9]

      int[] getMissingNum(int[] arr,int start,int length){
          int missLen=length-arr.length;
          int[] miss=new int[missLen];
          int[] temp=new int[length];
          for(int i=0;i<arr.length;i++){
              temp[arr[i]-start]=1; 
          }
          int index=0;
          for(int i=0;i<temp.length;i++){
              if(temp[i]==0){
                  miss[index]=i+start;
                  index++;
              }
          }

          return miss;
      }

完全排列组合

题目描述:列出包括几个不同字符的数组的所有排列组合形式。如[a,b,c]–abc,acb,bac,bca,cab,cba

  //也可以利用递归,第一个字符串一共有n种选择,剩下的变成一个n-1规模的递归问题。
      //而第一个字符的n种选择,都是字符串里面的。
      //因此可以使用第一个字符与1-n的位置上进行交换,得到n种情况,然后递归处理n-1的规模,只是处理完之后需要在换回来,变成原来字符的样子。
      public static void arrange(char[] chs, int start, int len){  
            if(start == len-1){  
                for(int i=0; i<chs.length; ++i)  
                    System.out.print(chs[i]);  
                System.out.println();  
                return;  
            }  
            for(int i=start; i<len; i++){ 

                char temp = chs[start];  
                chs[start] = chs[i];  
                chs[i] = temp;  
                arrange(chs, start+1, len);  
                temp = chs[start];  
                chs[start] = chs[i];  
                chs[i] = temp;  
            }  
        }  

猜你喜欢

转载自blog.csdn.net/m2920440052/article/details/56674778