2018 12 22 ARTS(10)

68 篇文章 0 订阅
49 篇文章 0 订阅

什么是 ARTS
Algorithm:每周至少做一个leetcode的算法题;
Review:阅读并点评至少一篇英文技术文章;
Tip/Tech:学习至少一个技术技巧;
Share:分享一篇有观点和思考的技术文章;

Algorithm 算法题

957 N 天后的牢房

https://leetcode-cn.com/problems/prison-cells-after-n-days/submissions/
其实一个最简单的思路就是逐个计算,根据规则其实是很快就能得到一个答案的,但是基本上可以确定这个答案是行不通的,因为潜意识就觉得,答案应该不是这么简单的。果然,时间超标。以下是未通过的答案:

int[] tempInt = new int[8];
        for (int i = 1; i <= N; i++) {
            tempInt = cells.clone();
            for (int j = 0; j < 8; j++) {
                if (j == 0 || j == 7) {
                    cells[0] = 0;
                    cells[7] = 0;
                    continue;
                }
                if (tempInt[j-1] == 0 && tempInt[j+1] == 0) {
                    cells[j] = 1;
                } else if (tempInt[j-1] == 1 && tempInt[j+1] == 1) {
                    cells[j] = 1;
                } else {
                    cells[j] = 0;
                }
            }
        }
        return cells;

因为那些通过的例子会把天数设置很大,比如100000天这种,那么逐个计算就会导致时间超标。
那么就需要找一个可以节省时间的方法,其实第一眼没发现很可惜的,但是基本上多看几次,就能观察到八位的数组,而且每个数组上都是0或者1,这个特征就是很容易联想到二进制。然后大概就会想到这八个位置上的0或者1的排列最后不会超过2的8次方。而像100000这种天数明显是远远超过2的8次方的。这样就容易想到有循环。当然,这个循环的周期是多少咱们并不知道,咱们只能去在答案中记录这个值。
这我们就可以设计一个HashMap,以二进制算出来的数字为key,天数为value。最后根据天数除周期取余来获取最后一天的key的值,来计算当前的数组。
注意两个点:
1 要记录开始进入循环的其实位置
2 记录循环的周期的值(其实后来通过一次一次尝试得知,其实是固定的 14)
3 要注意的最后的那次循环的数据会不会超过周期,导致map获取不到,这里需要最后的循环的数据进行取余一次。
答案不好,仅供参考:

class Solution {
    public int[] prisonAfterNDays(int[] cells, int N) {
        Map<Integer, Integer>  map = new HashMap<>();

        int[] tempInt = new int[8];
        int cycleBegin = 0;
        int cycleBeginI = 0;
        int i = 1;
        for (; i <= N; i++) {
            if (!map.containsKey(nums(cells))) {
                map.put(nums(cells), i);
            } else {
                cycleBegin = map.get(nums(cells));
                cycleBeginI = i;
                break;
            }
            tempInt = cells.clone();
            for (int j = 0; j < 8; j++) {
                if (j == 0 || j == 7) {
                    cells[0] = 0;
                    cells[7] = 0;
                    continue;
                }
                if (tempInt[j-1] == 0 && tempInt[j+1] == 0) {
                    cells[j] = 1;
                } else if (tempInt[j-1] == 1 && tempInt[j+1] == 1) {
                    cells[j] = 1;
                } else {
                    cells[j] = 0;
                }
            }
        }
        if (i == N + 1) {
            return cells;
        } else {
            int cycle = cycleBeginI - cycleBegin;
            int lastInCycle = (N - cycleBegin) % cycle;
            
            int resultIndex = cycleBegin + lastInCycle + 1;
            if ((lastInCycle + 1) == cycle) {
                resultIndex = cycleBegin + (lastInCycle + 1) % cycle;
            } 
            if (cycle == 1) {
                resultIndex = cycleBegin + lastInCycle;
            }
            Set<Integer> mapSet = map.keySet();
            for (int item : mapSet) {
                if (map.get(item) == resultIndex) {
                   return  getBinArray(item);
                }
            }
        }
        return null;
    }
    private int nums(int[] cells) {
        double result =  Math.pow(2, 0) * cells[0] + Math.pow(2, 1) * cells[1] + Math.pow(2, 2) * cells[2]
                    + Math.pow(2, 3) * cells[3] + Math.pow(2, 4) * cells[4] + Math.pow(2, 5) * cells[5]
                    + Math.pow(2, 6) * cells[6] + Math.pow(2, 7) * cells[7];
        return  (int) result;
    }

    private int[] getBinArray(int num) {
        int[] result = new int[8];
        int i = 0;
        while (num > 0) {
            result[i] = num % 2;
            i++;
            num = num / 2;
        }
        return result;
    }
}

Review 阅读并点评至少一篇英文技术文章

How to write Go middleware
特别平稳的一篇文章,这篇文章主要写了关于Go中间件的一些问题。

Tip/Tech:学习至少一个技术技巧

本周在的LeetCode做题的时候遇到需要使用“递减栈”才能够解决这样的问题,就查了一些关于这个递减栈的资料。其实都递减栈这个属于栈的用法中特殊的用法,单调栈,除了递减栈,还有递增栈。
简单归纳啥时候使用这些单调栈:

单调栈何时用: 为任意一个元素找左边和右边第一个比自己大/小的位置,用单调栈

Share:分享一篇有观点和思考的技术文章

The Meaning of Life
这篇文章的讨论的就是生命的意义是啥,那到底是啥呢?
作者不搞生命鸡汤,直接坦白的告诉你,你的生命的意义就是用你自己的方式活着。
生命就是生命。它没有任何意义。你想如何去生活对你来说完全可以,这个就是生命的意义了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值