递归算法一些例子---记录2/14情人节

package com.raisecom.tiap.ems.basic.mgt.domain.acl;


import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;

public class recursionInfo {
    public static void main(String[] args) {
        //System.out.println(1<<35);
        //System.out.println(1<<3);
        recursionInfo a = new recursionInfo();
        a.swap(5,10);
        //testInfo.placeOneOrZero(2,2);
        //a.findRepeatNum();
        //a.conutOne();
        //a.doubleBinary();
       // a.korOneCount();
       // a.printHanoiTower(3,"A","B","C");
        int [] arr = {7,6,5,4,3,2,1,100,99,7};
        //a.shellSort(arr);
        //testInfo.print(arr);

        //int b = a.binarySearch(arr,0,arr.length-1,100);
        //System.out.println(b);
        String [] str = {"a","","ac","","ad","b","","ba"};
        int res = a.indexOf(str,"baa");
        System.out.println(res);
    }
    public static void swap(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    public  static void print(int [] a)
    {
        System.out.println(Arrays.toString(a));
    }
    public void swap(int a, int b)
    {
        a = a^b;
        b = a^b;
        a=  a^b;
        //System.out.println("交换后 a="+a+" b="+b);

    }
    /**
     * 递归设计经验
     * 找重复(子问题)
     * 找重复中的变化量---参数
     * 找参数变化趋势---设计出口
     * 策略 直接量+小规模子问题和多个子规模问题变种
     * 或者可以对于数学问题找递推公式或者是等价转换
     * 循环改递归
     * 经典递归
     * 大量练习,总结规律,找套路
     *
     *
     */
     //求一个数的阶乘
    public int factorial(int n)
    {
        if (n==1){ //注意没有0的阶乘
            return 1;
        }
        else
        {
            return  n*factorial(n-1);
        }
    }
    //打印i到j,i小于j(用for循环但是需要递归)
    public void f1(int i, int j)
    {
        if (i>j) //出口
            return;
        System.out.println(i); //i为变化量
        f1(i+1,j);//重复
    }
   //打印数组元素
    public int  f2(int [] arr, int begin) //加参数进行出界口,递归的妙用
    {
        if (begin==arr.length-1)
            return arr[begin];
        return arr[begin] + f2(arr,begin+1);
    }
    //反转字符串 切的量在变,设计成参数
    public String reverse(String src,int end){
        if (end ==0)
        {
            return ""+src.charAt(0);
        }
        return src.charAt(end)+reverse(src,end-1);
    }
    //斐波那契数列 fn = fn-1+fn-2 n=1 或者n=2的为1 调用过程是先纵后横,先挖深再兄弟

    //对于最大公约数的球阀,可以用辗转相除法
    public  int gcd(int m, int n)
    {
        if (n==0)
            return m;
        return gcd(n,m%n);//辗转相除法
    }
    //插入排序用递归法:找到等价方式,前n-1个元素排好序,最后一个插入到以前的
    public void insertSort(int [] arr, int k)
    {
        if (k==0)
        {
            return;
        }
        //对前k-1个元素排序
        insertSort(arr, k-1);
        //把位置k的元素插入到前面部分
        int x = arr[k];
        int index = k-1;
        while(index >-1&&x<arr[index])
        {
            arr[index+1]=arr[index];
            index--;
        }
        arr[index+1] =x;
    }
    /*
       汉诺塔问题,将1-N从A移动到C,B为中转。
       思路1 1-N-1 移动到C,B为辅助,N从A移动到B,再把
       1-N从C移动到B,A为辅助。这是一个等价问题
       @param N 初始的N个从小到大的盘子,N为大的编号
       @param from 原始柱子
       @param to 目标柱子
       @param help 辅助柱子
     */
    public void printHanoiTower(int N, String from, String to, String help)
    {
        if (N==1) //边界
        {
            System.out.println("move " +N +" from  "+from +" to " +to);
            return;
        }
        printHanoiTower(N-1,from,help,to);//转换角色
        System.out.println("move " +N +" from "+from +" to " +to);
        printHanoiTower(N-1,help,to,from);

    }
    /**
     * 二分查找的递归问题
     * 思路全范围二分查找等价于三个子问题:
     * 左边找递归
     * 中间比
     * 右边查找递归 注意:左边查找和右边查找只选其一
     */
    public  int binarySearch(int[] arr, int low, int high, int key)
    {
        if (key<arr[low]||low > high|| key>arr[high]) //边界条件
            return -1;

        int mid = low+((high-low)>>1);
        int midVal = arr[mid];
        if (midVal<key)
            return binarySearch(arr, mid+1,high,key);
        else if (midVal>key)
            return binarySearch(arr,low,mid-1,key);
        else
            return mid;
    }

    /**冒泡(交换),插入(挪动数组),选择(最大最小),
     * 希尔排序是一种插入排序,是称为缩小增量排序
     *思路:一趟一个增量,用增量来分组,组内执行插入排序
     *
     */
    public void shellSort(int [] arr)
    {
        for (int interval = arr.length/2; interval>0;interval=interval/2)
        {
            for (int i =interval; i<arr.length;i++) {
                int target = arr[i];
                int j = i - interval;
                while (j > -1 && target < arr[j]) {
                    arr[j + interval] = arr[j];
                    j-=interval;
                }
                arr[j + interval] = target;
            }
        }

    }
    /**小白上楼梯,有n阶楼梯,一次可以上1阶,2阶,或者3阶,
     * 小白有多少种方法走完楼梯
     * 思路:用递归
     *
     */
    public int walkCount(int n){

        if (n==0) return 1;//这个有点牵强
        if (n==1) return 1;
        if (n==2) return 2;//注意这个容易出错
        return walkCount(n-1)+walkCount(n-2)+walkCount(n-3);//这个和斐波那契数列想法一样?

    }
    /**旋转数组的最小数字
     * 把一个数组最开始的若干个元素搬到数组末尾,
     * 输入一个递增排序的数组的一个旋转,输出旋转数组最小元素。
     *思路:有序性代表的就是二分查找,从中间划一刀分为左右两部分
     * 12345----34512旋转后数组,最小值是在无序数组的一侧,再划
     * 切分,最终切分成两个元素就找到了
     */
    public int minValue(int [] arr)
    {
        int begin = 0;
        int end = arr.length -1;
        //考虑没有旋转特殊情况
        if (arr[begin]<arr[end])
            return arr[begin];

        while(begin +1 <end)
        {
            int mid = begin + ((end-begin)>>1); //注意数组的特殊情况{01111}
            if (arr[mid]>=arr[begin]){ //左侧有序
                begin=end;
            }else {
                end = mid;
            }
        }
        return arr[end];
    }
    /**
     * 有空字符串的有序字符数组中查找,找出给定字符串的索引
     *思路:
     */
    public int indexOf(String [] str, String p)
    {
        int begin = 0;
        int end = str.length-1;
        while (begin<=end)
        {
            int midIndex = begin + ((end-begin)>>1);//注意放到循环外边的话,死循环
            while (str[midIndex].equals("")){
                midIndex++;
                if (midIndex >end) //防止死循环一直走空串其它
                    return -1;
            }
            if (str[midIndex].compareTo(p)>0)
            {
                end = midIndex-1;
            }
            else if (str[midIndex].compareTo(p)<0)
            {
                begin = midIndex+1;
            }
            else
            {
                return midIndex;
            }
        }
         return  -1;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值