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