• 各种算法七


    各种算法七

        在第六篇中,我简单的提了一下递归的思想;至于什么是递归,以及我对递归的理解,你可以看我的这篇博文:http://www.cnblogs.com/mc67/p/5114008.html

    如果,不理解递归就看上面的图,如果还是不理解,就自己百度;

    1.递归应用:阶乘函数

    递归的作用在于把问题的规模不断缩少,直到问题缩少到能简单地解决

    阶乘n!= 1 * 2 * 3 * 4 * ··· * n 

             //具体的实现;
            //ps阶乘的英文是:factorial
            public static int factorial(int n)
            {
                if (n == 1)
                {
                    return 1;
                }
                else
                {
                    return  n * factorial(n - 1);
                }
    
            }

    然后就是我们的....

    2.递归的应用输入 n,求斐波那契数列第n个数,

       这到道题可以说是被我们的面试官考烂的一道一呀;

       首先你得要找出斐波那契数的规律滴啊:0 1 1 2 3 5 8 13 21......

       第3项开始,每一项都等于前两项之和

     public static int fibonacci(int n)
            {
                if (n == 0) { return 0; }
                if (n == 1) { return 1; }
                //从第三项,开始,我们的规律就出来了滴啊;
                return fibonacci(n) + fibonacci(n - 1);
                //这个及时我们的额规律滴哎呀;,效果还是不错滴哎呀
            }

    3.递归的应用:找到我们的回文数滴呀

     首先你要理解什么是我们的额回文数滴呀;

    就是一个字符串,从左到右边,以及从右到左边,完全是一样的;level aoa oco aabb

    递归的作用在于把问题的规模不断缩少,直到问题缩少到能简单地解决

    1. 字符串长度可能会奇数或偶数:

    • 如果字符串长度是奇数,字符串会剩下最中间那位字符,但其不影响回文。当检查到长度为1的时候即代表此字符串是回文
    • 如果字符串长度是偶数,当两端的字符串两两比较检查后不会剩下字符。即检查到长度为0的时候即代表此字符串是回文

    2. 如果检查到两端两个字符不相同。则说明此字符串不是回文,直接返回0,不需要继续检查

    数组问题存在奇数和偶数的情况是,我们一般不用 len/2 的方式,而使用的是我们的low 和 high 两个类似指针的效果来进行寻找滴哎呀;

            //接下来是我们回文数的 判断滴啊;
            public static int fun(int low, int high, string arr, int length)
            {
                //数组的长度在不断的减小滴呀;
                if (length == 0 || length == 1) { return 1;}
                if (arr[low] != arr[high]) { return 0; }
                //否则就继续查找;匹配滴呀;
                return  fun(low+1,high-1,arr,length-2);
                
            }

    效果还是不错滴呀;不过,当然有我们的优化方式了滴呀;效果还是不错滴呀;

    public static int fun2(int low, int high, string arr)
            {
                if (low < high)
                {
                    if (arr[low] != arr[high]) { return 0; }
    
                    return fun2(low + 1, high - 1, arr);
                }else
                {
                    return 1; //两个指针都已经超出了,还没遇到不想等的值,我们就返回一滴呀;
                }
    
            }

    4.递归的应用:字符串反转;

     将字符串 fuck 翻转,变为kcuf

    先看看我们的常规方式的呀;

     public static void reverseString( string val)
            {
                //最low的方式,
                var newString = "";
                var len = val.Length;
                for(var i = 0; i < len; i++)
                {
                    newString += val[len-1-i];
                }
                Console.WriteLine(newString);
    
                //low逼方式二
                string str = "";
                for(var i = len - 1; i >= 0; i--)
                {
                    str += val[i]; //这样是我们的额low方式之一滴呀;
                }
                Console.WriteLine("low method :{0}",str);
                Console.WriteLine();
    
                //当然有我们的方式三滴呀;效果还是不滴呀;
                var low = 0;
                var high = len - 1;
                //折是一种交换的方式滴呀;
                var arr = val.ToArray();
                for(var i = 0; i < len; i++)
                {
                    if (low < high) //用这种方式就不存在所谓的奇数个 和 偶数个的区分了滴呀;效果还是不错i呀;
                    {
                        //这里可以加一个判断,如果相同,就不交换滴啊;
                        if(arr[low]!=arr[high])
                        {
                            char temp = arr[low];
                            arr[low] = arr[high];
                            arr[high] = temp;
                        }
                        low++;  //这里我们可以将i 和low high 三个变量关联起来,但是,没这个必要,否则逻辑就不清晰了;
                        high--;
                    }else
                    {
                        break;
                    }
    
                }
                foreach (var i in arr)
                {
                    Console.Write(i.ToString());
                }
    
            }

    接下来就是我们的优化了滴呀;

    接下来使用我们的递归进行各种优化滴呀;效果还是不错i哎呀;然后..........

    你会发现上面的代码都是嵌套在我们的for 循环中滴啊;那么我们可以使用递归来替换滴啊;

    public static  int reverseStr(int low,int high,char [] arr,int length)
            {
              
               if (length==0 || length == 1)
                {
                    return 0;
                }
                if (arr[low] != arr[high])
                {
                    char temp = arr[low];
                    arr[low] = arr[high];
                    arr[high] = temp;
                }
                return reverseStr(low+1,high-1,arr,length-2);
    
            }

    最后额效果还是不错滴呀

    最后的优化滴呀;

      

           public static  int reverseStr(int low,int high,char [] arr)
            {
              
               if (low>high)
                {
                    return 0; //这种方式也是可以滴呀;//而且效果不错滴呀;
                }
                if (arr[low] != arr[high])
                {
                    char temp = arr[low];
                    arr[low] = arr[high]; //这里就是交换的事项滴啊
                    arr[high] = temp;
                }
                return reverseStr(low+1,high-1,arr);
    
            }

    5.递归的应用:折半查找滴啊;

      这种查找,的前提是我们的数组是有序的顺序滴呀;才有折半意义滴呀;查找又是另外一个比较大的话题了;

     第一种查找:漫无目的的遍历;

     第二种查找:折半循环查找;可以将循环的次数减少为:len/2 但是这种方式仅仅限于偶数个的数组中,奇数的话,无法整除,但是我们可以使用low 和 high两个指针滴呀;

     第三种查找:对有序数组的这边查找,现在我们讨论的就是现在这种滴呀;

     还是先看我们比较low的算法,然后再一步一步的优化吧

            public static int LookUpIndex()
            {
                string str = "fuck the life";
                char key = 'e';//找到第一个就停止了;
                int len = str.Length;
                int low = 0;
                int high = len - 1;
                //一般又是一个循环
                for (var i = 0; i < len; i++)
                {
                    if (low > high) return -1;
                    if (str[low] == key) { return low; };//返回下标
                    if (str[high] == key) { return high; } //返回下标
                    low++;
                    high--;
                }
                return -1;
            }

    用我们的递归来替换我们的for循环滴啊;

            public static int LookUpIndex2(int low,int high,int [] arr,int key)
            {
                //记住这查找的是我们额有序数组滴呀;
                
                int middle = (low + high) / 2;
                if (arr[middle] == key) { return middle; } //这里就不能返回执行的数字的额小标了;
                if (low > high) { return 0; } //终止我们循环的条件滴呀;我不知道这个算不算我们正规意义上的递归滴呀;
                if (arr[middle] > key)
                {
                    //在左边进行查找//就要移动我们额high
                    high = middle - 1;
                    return LookUpIndex2(low,high,arr,key);
    
                }else
                {
                    //在右边进行查找滴啊
                    low = middle + 1;
                    return LookUpIndex2(low, high, arr, key);//继续我们的额折半查找滴哎呀;
                    
                }
                
            }

    这样我们递归的常用方式就总结到这里滴啊;

  • 相关阅读:
    Spinlock
    Leetcode: Summary Ranges
    Leetcode: Search a 2D Matrix
    Leetcode: Rotate Image
    Leetcode: Length of Last Word in python
    BBC-unit7 session1
    BBC-unit6 session5
    BBC-unit6 session4
    BBC英语-unit6 session3
    BBC英语-unit6 session2
  • 原文地址:https://www.cnblogs.com/mc67/p/6219366.html
Copyright © 2020-2023  润新知