zoukankan      html  css  js  c++  java
  • 每天两题03

    题目一:旋转数组的最小数字

      思路:说实话看这个题目看了好久题目愣是没看懂,到底是个什么数组啊,又不说清楚,emmm...百度了好久才知道这个数组默认其中的元素的递增的,而且在数组中的元素可能是重复的,比如2344445这种也是行的,我们就分别讨论一下有重复元素和没有重复元素的情况;

      第一种情况:数组中没有重复元素;

      顺便提一句,所谓的数组的旋转,就是每次讲第一个元素放到数组的最后一个位置,比如说上面的1234旋转一下是2341,再旋转就是3412,再旋转就是4123,等等,我们可以把这些旋转后的数组叫做原数组的一个旋转

      不知道大家有没有发现,1234数组的这么多旋转中,如果都从中间进行切分,那么可以看到一半是从小到大进行排序的,另外一半是没有顺序的,而且很明显的是最小的元素始终都是在没有顺序的那一半中,到这里我们可以想到一个很简单的办法,就是每次都将数组且一般,找没有顺序的那个数组,然后对这个没有顺序的数组继续进行同样的切分,直至最后找到最小元素,这种方式也叫做二分法。

      这里数组不管是奇数还是偶数都一样:

    public static int min(int[] arr){
            int left=0;//数组最左边的位置
            int right=arr.length-1;//数组最右边的位置
            
            while (left<right) {
                int midd=(right+left)/2;//数组中间的位置
                if (arr[left]<=arr[midd]) {
                    left=midd+1;
                }else{
                    right=midd;
                }
            }
            return arr[left];
        }
        
        public static void main(String[] args) {
            int[] arr = {17,1,3,7,9,10};
            int[] arr2 = {5,6,10,17,1};
            System.out.println(min(arr));//1
            System.out.println(min(arr2));//1
        }

      第二种情况:数组中有重复的元素,我们可以试试,即使数组中有重复的元素,比如原始数组1222334,我们将它进行旋转,2223341,2233412,2334122,其实还是保持着第一种情况中的规律:将数组从中间进行拆分,一半是有顺序的,一半是没有顺序的,注意:这里有一种特殊情况,比如原数组是01111,经过两次旋转之后就是11101,此时从中间切分会发现arr[left] == arr[midd] == arr[right],无法通过比较判断哪边是有顺序的,哪边是没有顺序的;

      所以如果是这种特殊情况,这里我们就用最简单的遍历去找到其中最小的值就可以了,代码跟上面差不多:

    public static int minRotate(int[] arr){
            int left=0;
            int right=arr.length-1;
            while(left<right){
                int midd = (left+right)/2;
                
                //这里就是多了一步处理,其他的代码都是和第一种情况一样的
                if (arr[left] == arr[midd] && arr[midd] == arr[right]) {
                    for (int i = left; i < right; i++) {
                        if (arr[i]<arr[i+1]) {
                            return arr[i];
                        }
                    }
                    return arr[left];
                }else if (arr[midd] <= arr[right]) {
                    right = midd;
                }else{
                    left = midd+1;
                }
            }
            return arr[left];
        }
        
        public static void main(String[] args) {
            int[] arr = {17,1,3,7,9,10};
            int[] arr2 = {5,6,10,17,1};
            int[] arr3 = {5,5,5,2,5};
            System.out.println(minRotate(arr));//1
            System.out.println(minRotate(arr2));//1
            System.out.println(minRotate(arr3));//2
        }

    题目二:剪绳子

       一根长度为n的绳子,剪成多段,每一段都是整数,使得这些整数相乘结果最大;我们可以简单的知道,n=2,最大乘积是1;n=3时,最大乘积是2;n=4时,最大乘积是2x2=4;n=5时,最大乘积是2x3=6。。。

      那么我们现在要知道,将绳子的每一段尽量剪成多少是最合适的呢?

      这里比较奇葩,好像是有这么一个规律,当n>=5的时候,对于任意的n,都有这么的一个结论:2(n-2)>n,3(n-3)>n,我们将这两个不等式拆开可以知道就是n>4和n>4.5(可以看到拆开并没什么用),其实我有一个想法,就是首先将长度为n的绳子尽量剪短成长度A,然后再将每一段剪成两段B和C,这两段的乘积BC要大于A,最后算出来的乘积才是最大的!然后根据上面的不等式可以看到,最好的就是剪成的每一段A都可以被2或者3整除,换句话说就是尽量剪成2或者3这个长度的,而且对于同一长度来说,3(n-3)>2(n-2),最好剪成3,是在不行的话才剪成2(一定不要剪成1,这么不用多说吧。。。如果有个1,那就将3中一个1丢给1,组成2x2)

      大概就是这么一个逻辑,代码实现:

    public static int max(int n){
            if (n<2) {
                return 0;
            }
            if (n==2) {
                return 1;
            }
            if (n==3) {
                return 2;
            }
            //优先计算这个绳子可以拆开为多少个3,假如绳子剪掉了这么多3,余下的长度为1,那么就少剪掉一个3,和1拼成4
            //然后剪成两个2
            int num3 = n/3;
            if((n-num3*3)==1){
                num3--;
            }
            //这里就是计算绳子剪掉了很多的3之后还有多少个2
            int num2 = (n-num3*3)/2;
            //最后就是将这么多的3相乘,所有的2相乘,然后两个结果相乘
            return (int) Math.pow(3, num3)*(int)Math.pow(2, num2);
            
            
        }
    
        public static void main(String[] args) {
            System.out.println(max(6));//9
    
        }
  • 相关阅读:
    poj 2312 Battle City
    poj 2002 Squares
    poj 3641 Pseudoprime numbers
    poj 3580 SuperMemo
    poj 3281 Dining
    poj 3259 Wormholes
    poj 3080 Blue Jeans
    poj 3070 Fibonacci
    poj 2887 Big String
    poj 2631 Roads in the North
  • 原文地址:https://www.cnblogs.com/wyq1995/p/11546459.html
Copyright © 2011-2022 走看看