leetcode 20

在这里插入图片描述
很难 一般不考
在这里插入图片描述
inplace算法 重要
f(i,N) 给定一个i位置,知道最终在哪个位置
当长度是3^k-1 环的起始点是1,3,。。。 3 k − 1 3^{k-1} 3k1

import javax.print.event.PrintEvent;

public class ShuffleProblem {
    public static void shuffle(int[] arr,int L,int R){
        while(R - L + 1 > 0){
            int len = R - L + 1;
            int base = 3;
            int k = 1;
            while(base <= (len + 1)/3){
                base *= 3;
                k++;
            }

            int half = (base - 1)/ 2;
            int mid = (L + R)/2;

            rotate(arr,L+half,mid,mid+half);
            cycles(arr,L,base-1,k);
            L = L + base - 1;
        }
        public static void cycles(int[] arr,int start,int len,int k){
            for (int i = 0,trigger = 1; i < k ; i++,trigger*=3) {
                int preValue = arr[trigger+start-1];
                int cur = modifyIndex(trigger,len);
                while(cur != trigger){
                    int tmp = arr[cur + start -1];
                    arr[cur + start -1] = preValue;
                    preValue = tmp;
                    cur = modifyIndex(cur,len);
                }
                arr[cur + start -1] = preValue;
            }
        }
        public static void rotate(int[] arr,int L,int M,int R){
            reverse(arr,L,M);
            reverse(arr,M+1,R);
            reverse(arr,L,R);
        }
    }
}

在这里插入图片描述

import java.util.Stack;

public class VisbleMountains {

    //栈中的记录 从顶到di  由小到大
    public static class Record{
        public int value;
        public int times;//收集的次数

        public Record(int value){
            this.value = value;
            this.times = 1;
        }
    }

    public static int getVisbleNum(int[] arr){
        if(arr == null || arr.length < 2){
            return 0;
        }
        int N = arr.length;
        int maxIndex = 0;
        //在环中找最大值在环中的位置
        for (int i = 0; i < N; i++) {
            maxIndex = arr[maxIndex] < arr[i] ? i : maxIndex;
        }

        Stack<Record> stack = new Stack<Record>();
        //吧
        stack.push(new Record(arr[maxIndex]));
        //从最大值的下一个位置查找
        int index = nextIndex(maxIndex,N);
        //统计结果
        int res = 0;

        //遍历开始,再次相等说明转了一圈
        while(index != maxIndex){
            while(stack.peek().value < arr[index]){
                int k = stack.pop().times;
                //getInternalSum 是组合数Ck2
                res += getInternalSum(k) + 2 * k;
            }
            //下面是栈内的元素大于等于arr【index]的情况
            if(stack.peek().value == arr[index]){//相等的情况
                stack.peek().times++;
            }else{
                stack.push(new Record(arr[index]));
            }

            index = nextIndex(index,N);
        }
        //清算阶段 ,只剩下栈内的元素
        while(stack.size() > 2){
            int times = stack.pop().times;
            res += getInternalSum(times) + 2 * times;
        }

        if(stack.size() == 2){
            int times = stack.pop().times;
            res += getInternalSum(times)
                    + (stack.peek().times == 1 ? times : 2 * times);
        }
        //这里我感觉有点问题 剩下最后一个最大的元素了,如果这个元素的个数大于1用这个没问题,内部Ck2,如果等于1.。应该是0吧。。
        res += getInternalSum(stack.pop().times);
        return res;
    }

    public static

    //i的下一个位置
    public static int nextIndex(int i,int size){
        return i < (size - 1) ? (i + 1) : 0;
    }

    //i的上一个位置
    public static  int lastIndex(int i,int size){
        return i > 0 ? (i-1) : (size -1);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值