Leetcode 初级算法 - 设计问题

版权声明:Shared With Do What The Fuck You Want To Public License https://blog.csdn.net/nekonull/article/details/86505878

Leetcode 初级算法 - 设计问题

原始地址:https://github.com/jerrylususu/leetcode-easy
二级标题格式:[章节内题号] [题库内题号] [题目标题]

1 384 打乱数组 (Shuffle an Array)

我的思路:一开始我想的是通过Random得到一个随机数 然后用一个boolean[] used来跳过已经被用过的数字… 但后来意识到这样做太慢了… (而且似乎结果会报错…)

然后就改了思路 用类似于选择排序的做法 先从前面[0,n-i-1]个数中间随便选一个数 和后面n-i-1位置上的数字交换 洗牌算法 Fisher-Yates Algorithm (小坑:System.arraycopy 全是小写)

class Solution {

    int[] current;
    int[] original;
    
    public Solution(int[] nums) {
        this.original = nums;
    }
    
    /** Resets the array to its original configuration and return it. */
    public int[] reset() {
        this.current = this.original;
        return this.current;
    }
    
    /** Returns a random shuffling of the array. */
    public int[] shuffle() {
        int n = this.original.length;
        this.current = new int[n];
        System.arraycopy(this.original,0,this.current,0,n);
        Random r = new Random();
        for(int i=0;i<n;i++){
            int pos = r.nextInt(n-i);
            swap(this.current,pos,n-1-i);
        }
        return this.current;
    }
    
    public static void swap(int[] arr, int a, int b){
        int tmp = arr[a];
        arr[a]=arr[b];
        arr[b]=tmp;
    }
}

其他思路:还能直接暴力…两个list 每次从第一个里随机取出放到第二个…

2 155 最小栈

我的思路:显然是双栈法

坑:如果smin是空的 就peek不出来 需要加一个特判

class MinStack {
    
    Stack<Integer> s;
    Stack<Integer> smin;

    /** initialize your data structure here. */
    public MinStack() {
        s = new Stack<>();
        smin = new Stack<>();
    }
    
    public void push(int x) {
        s.push(x);
        if(smin.size()==0) smin.push(x);
        else smin.push(x<smin.peek()?x:smin.peek());
    }
    
    public void pop() {
        s.pop();
        smin.pop();
    }
    
    public int top() {
        return s.peek();
    }
    
    public int getMin() {
        return smin.peek();
    }
}

其他思路:可以通过存储最小值和当前值的差值 使用一个栈完成 来源

具体实现:存一个min 栈上存储current-min 如果current比min小就更新min
在pop的时候 如果发现栈顶是一个负数 那么说明最小值在这个操作被更新了 pop的时候不仅需要min+pop() 还需要把最小值恢复到上一个状态 即min=min-peek()

坑:需要全程用Long 输出的时候再转换回去 (最大差值可能是Integer.MAX_VALUE-Integer.MIN_VAUE)

// source:https://leetcode.com/problems/min-stack/discuss/49031/Share-my-Java-solution-with-ONLY-ONE-stack

public class MinStack {
    long min;
    Stack<Long> stack;

    public MinStack(){
        stack=new Stack<>();
    }
    
    public void push(int x) {
        if (stack.isEmpty()){
            stack.push(0L);
            min=x;
        }else{
            stack.push(x-min);//Could be negative if min value needs to change
            if (x<min) min=x;
        }
    }

    public void pop() {
        if (stack.isEmpty()) return;
        
        long pop=stack.pop();
        
        if (pop<0)  min=min-pop;//If negative, increase the min value
        
    }

    public int top() {
        long top=stack.peek();
        if (top>0){
            return (int)(top+min);
        }else{
           return (int)(min);
        }
    }

    public int getMin() {
        return (int)min;
    }
}

猜你喜欢

转载自blog.csdn.net/nekonull/article/details/86505878