There is a room with n lights which are turned on initially and 4 buttons on the wall. After performing exactly m unknown operations towards buttons, you need to return how many different kinds of status of the n lights could be.
Suppose n lights are labeled as number [1, 2, 3 ..., n], function of these 4 buttons are given below:
Flip all the lights.
Flip lights with even numbers.
Flip lights with odd numbers.
Flip lights with (3k + 1) numbers, k = 0, 1, 2, ...
Example 1:
Input: n = 1, m = 1.
Output: 2
Explanation: Status can be: [on], [off]
Example 2:
Input: n = 2, m = 1.
Output: 3
Explanation: Status can be: [on, off], [off, on], [off, off]
Example 3:
Input: n = 3, m = 1.
Output: 4
Explanation: Status can be: [off, on, off], [on, off, on], [off, off, off], [off, on, on].
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/bulb-switcher-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
优化点:
操作1是全转换,操作2和操作3是每两个转换一次,操作4是每三个转换一次。所以,以他们最小公倍数,6,不管怎么变化,k+0~k+5,k+6~k+11,k+12~k+17....(k < 6)每6个的状态是一样的。那么我们只用管前六个的可能,于是我们可以截取n的前一段,如果n大于6,那么对n取模 + 6即可。
用一个Integer的state来储存当前的状态,它的二进制表示中,0代表关灯,1代表开灯。四中变化形态,可以用位运算表示。
对state进行m次遍历,每遍都得到其分别进行四次变化后的结果,放在一个数组中。然后再对数组中的数字,进行第二次遍历。注意每次都排除相同的结果,避免重复运算。
class Solution {
int num = 0;
public int flipLights(int n, int m) {
num = (n <= 6) ? n : (n % 6 + 6);
Set<Integer>set = new HashSet<>(); // 排除相同状态
Queue<Integer>queue = new ArrayDeque<>();
queue.add((1 << n) - 1);
for (int i = 0; i < m; i++) {
int qSize = queue.size();
set.clear();
for (int j = 0; j < qSize; j++) {
int top = queue.remove();
int[] res = new int[]{change1(top), change2(top), change3(top), change4(top)};
for(int re: res) {
if (set.contains(re)) {
continue;
}
set.add(re);
queue.add(re);
}
}
}
return queue.size();
}
int change1(int states){
int t = (1 << num) - 1;
return states ^ t;
}
int change2(int states){
for (int i = 0; i < num; i = i + 2) {
states ^= (1 << i);
}
return states;
}
int change3(int states){
for (int i = 1; i < num; i = i + 2) {
states ^= (1 << i);
}
return states;
}
int change4(int states){
for (int i = 0; i < num; i = 3 * i + 1) {
states ^= (1 << i);
}
return states;
}
}