Leetcode刷题 2021.02.13

Leetcode957 N 天后的牢房

8 间牢房排成一排,每间牢房不是有人住就是空着。

每天,无论牢房是被占用或空置,都会根据以下规则进行更改:

如果一间牢房的两个相邻的房间都被占用或都是空的,那么该牢房就会被占用。
否则,它就会被空置。
(请注意,由于监狱中的牢房排成一行,所以行中的第一个和最后一个房间无法有两个相邻的房间。)

我们用以下方式描述监狱的当前状态:如果第 i 间牢房被占用,则 cell[i]==1,否则 cell[i]==0。

根据监狱的初始状态,在 N 天后返回监狱的状况(和上述 N 种变化)。

看到N的大小就感觉这题肯定是会有循环的,一开始想要是一直不循环怎么办。后来看到大小一共就是8,那么不管怎么样一共可能的个数就是256个。题解好像验证了只要14次就会出现循环。

class Solution {
    
    
	//需要一个set记录是否出现过,一个list,记录出现的情况
	//其实感觉不需要set,只要记录第一个就行了。
    Set<Integer> set = new HashSet<>();
    List<int[]> list = new ArrayList<>();
    public int[] prisonAfterNDays(int[] cells, int N) {
    
    
        int n = cells.length;
        for(int k = 0; k < N; k++){
    
    
        //进行模拟
            int[] res = new int[cells.length];
            for(int i = 1; i < n - 1; i++){
    
    
                if ((cells[i - 1] == 0 && cells[i + 1] == 0) || (cells[i - 1] == 1 && cells[i + 1] == 1)){
    
     
                res[i] = 1;
                }
            }
            // System.out.println(Arrays.toString(res));
            int temp = hash(res);
            //如果出现过了,就返回第(N - k - 1) % size个
            if (set.contains(temp)){
    
    
                int size = list.size();
                return list.get((N - k - 1) % size);
            }else{
    
    
            //否则加入到set和list中
                set.add(temp);
                list.add(res);
            }
            for(int j = 0; j < 8; j++) cells[j] = res[j];
            //如果没有出现过,又结束循环了就直接返回
            if (k == N - 1) return res;
        }
        return new int[]{
    
    };
    }
	
	//数组写一个hash函数
    private int hash(int[] num){
    
    
        int sum = 0;
        for(int i = 0; i < num.length; i++){
    
    
            sum += (int)Math.pow(2, i) * num[i];
        }
        return sum;
    }
}

Leetcode991 坏了的计算器

在显示着数字的坏计算器上,我们可以执行以下两种操作:

双倍(Double):将显示屏上的数字乘 2;
递减(Decrement):将显示屏上的数字减 1 。
最初,计算器显示数字 X。

返回显示数字 Y 所需的最小操作数。

正着想不太好想,所以可以试着倒着来。因为只有乘以2,或者减1。所以如果大于目标值,就只能一直减。
倒着想如果是奇数,就不可能是一个数乘以2达到的。所以只能是减一,如果是偶数的话,就是一个数乘以2达到的。
写的有点乱,其实也不知道这个为什么是对的。可能题刷多了就自动有思路了吧。

class Solution {
    
    
    public int brokenCalc(int X, int Y) {
    
    
        int res = 0;
        while(X < Y){
    
    
            if (Y % 2 != 0){
    
    
                Y++;
            }else{
    
    
                Y = Y/2;
            }
            res++;
        }
        res += X - Y;
        return res;
    }
}

Leetcode1027 最长等差数列

给定一个整数数组 A,返回 A 中最长等差子序列的长度。

回想一下,A 的子序列是列表 A[i_1], A[i_2], …, A[i_k] 其中 0 <= i_1 < i_2 < … < i_k <= A.length - 1。并且如果 B[i+1] - B[i]( 0 <= i < B.length - 1) 的值都相同,那么序列 B 是等差的。

基本的动态规划题,用HashMap作为dp数组,可以用整形数组,提升效率。

class Solution {
    
    
    public int longestArithSeqLength(int[] A) {
    
    
        int n = A.length;
        Map<Integer, Integer>[] map = new Map[n];
        for(int i = 0; i < n; i++){
    
    
            map[i] = new HashMap<>();
        }
        for(int i = 0; i < n; i++){
    
    
            for(int j = 0; j < i; j++){
    
    
                int diff = A[i] - A[j];
                //如果之前的元素没有递增序列或者,该差值不存在
                if (map[j].size() == 0 || !map[j].containsKey(diff)){
    
    
                //就加入差值,初始化为2
                    map[i].put(diff, 2);
                }else if (map[j].containsKey(diff)){
    
    
                //如果该元素有这个差值,更新一下最大值
                    if (map[i].containsKey(diff)){
    
    
                        if (map[j].get(diff) + 1 > map[i].get(diff)){
    
    
                            map[i].put(diff, map[j].get(diff) + 1);
                        }
                    }else{
    
    
                    //否则也直接加入之前的最大长度+1
                        map[i].put(diff, map[j].get(diff) + 1);
                    }
                }
            }
        }
        //遍历一遍取最大值
        int res = 0;
        for(int i = 0; i < map.length; i++){
    
    
            for(Integer key : map[i].keySet()){
    
    
                res = Math.max(res, map[i].get(key));
            }
        }
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43447128/article/details/113804736