• 【数组】灯泡开关 Ⅱ


    题目描述

    房间中有 n 只已经打开的灯泡,编号从 1 到 n 。墙上挂着 4 个开关 。

    这 4 个开关各自都具有不同的功能,其中:

    开关 1 :反转当前所有灯的状态(即开变为关,关变为开)
    开关 2 :反转编号为偶数的灯的状态(即 2, 4, ...)
    开关 3 :反转编号为奇数的灯的状态(即 1, 3, ...)
    开关 4 :反转编号为 j = 3k + 1 的灯的状态,其中 k = 0, 1, 2, ...(即 1, 4, 7, 10, ...)
    你必须 恰好 按压开关 presses 次。每次按压,你都需要从 4 个开关中选出一个来执行按压操作。

    给你两个整数 n 和 presses ,执行完所有按压之后,返回 不同可能状态 的数量。

    示例 1:

    输入:n = 1, presses = 1
    输出:2
    解释:状态可以是:
    - 按压开关 1 ,[关]
    - 按压开关 2 ,[开]

    解题思路

    这道题可以通过数学方法找到规律,这里我提供一套暴力思路和代码实现,如果直接跑会超时:

    • 准备4个计算方法,分别实现开关1、开关2、开关3、开关4的计算;
    • 准备一个set用于记录每次计算后的结果,并且做去重操作,从数据上分析重复度很高;
    • 准备一个list用于记录做4个计算方法后的结果情况;
    • 数据准备阶段将int[] array = new int[n]; 初始化,全部设置成1;并且加入到List种
    • 从0到presses进行遍历
      • 遍历List中所有的元素;
        • 执行4中计算方法;
        • 如果不在newSet中,则放到newList中和newSet中;
      • 遍历完成List,更新 list = newList ; set = newSet;
    • 遍历完成后返回list.size();

    按照上述思路代码实现如下:

    1. import java.util.*;
    2. class Solution1 {
    3. public int flipLights(int n, int presses) {
    4. if (presses == 0) {
    5. return 1;
    6. }
    7. int[] array = new int[n];
    8. Arrays.fill(array, 1);
    9. Set set = new HashSet<>();
    10. set.add(Arrays.toString(array));
    11. List<int[]> list = new ArrayList<>();
    12. list.add(array);
    13. for (int i = 0; i < presses; i++) {
    14. Set newSet = new HashSet<>();
    15. List<int[]> newList = new ArrayList<>();
    16. for (int[] arr : list) {
    17. int[] arr1 = cal1(arr);
    18. String s1 = Arrays.toString(arr1);
    19. if (!newSet.contains(s1)) {
    20. newList.add(arr1);
    21. newSet.add(s1);
    22. }
    23. int[] arr2 = cal2(arr);
    24. String s2 = Arrays.toString(arr2);
    25. if (!newSet.contains(s2)) {
    26. newList.add(arr2);
    27. newSet.add(s2);
    28. }
    29. int[] arr3 = cal3(arr);
    30. String s3 = Arrays.toString(arr3);
    31. if (!newSet.contains(s3)) {
    32. newList.add(arr3);
    33. newSet.add(s3);
    34. }
    35. int[] arr4 = cal4(arr);
    36. String s4 = Arrays.toString(arr4);
    37. if (!newSet.contains(s4)) {
    38. newList.add(arr4);
    39. newSet.add(s4);
    40. }
    41. }
    42. list = newList;
    43. }
    44. return list.size();
    45. }
    46. int[] cal1(int[] array) {
    47. int[] res = Arrays.copyOf(array, array.length);
    48. for (int i = 0; i < res.length; i++) {
    49. res[i] ^= 1;
    50. }
    51. return res;
    52. }
    53. int[] cal2(int[] array) {
    54. int[] res = Arrays.copyOf(array, array.length);
    55. for (int i = 0; i < res.length; i++) {
    56. if (i % 2 == 0) {
    57. res[i] ^= 1;
    58. }
    59. }
    60. return res;
    61. }
    62. int[] cal3(int[] array) {
    63. int[] res = Arrays.copyOf(array, array.length);
    64. for (int i = 0; i < res.length; i++) {
    65. if (i % 2 == 1) {
    66. res[i] ^= 1;
    67. }
    68. }
    69. return res;
    70. }
    71. int[] cal4(int[] array) {
    72. int[] res = Arrays.copyOf(array, array.length);
    73. for (int i = 0; i < res.length; i++) {
    74. if (i % 3 == 0) {
    75. res[i] ^= 1;
    76. }
    77. }
    78. return res;
    79. }
    80. public static void main(String[] args) {
    81. Solution1 solution = new Solution1();
    82. System.out.println(solution.flipLights(1, 1));
    83. System.out.println(solution.flipLights(2, 1));
    84. System.out.println(solution.flipLights(3, 1));
    85. }
    86. }

    总结

    这道题直接按照这个代码实现,执行时会超时;说明这道题不能按照暴力方法来解决,那么可以通过分析规律来解决;这里我暂时不提供解决方案,欢迎回复更简洁、高效的思路。

  • 相关阅读:
    有关有向图和无向图
    Java-比较器Comparable与Comparator(详解)
    【面试刷题】——函数指针和指针函数
    Mysql为何不推荐写多表SQL
    Facebook类似受众的具体创建步骤
    【Proteus仿真】【51单片机】锂电池管理系统
    后量子时代,未来密码该何去何从?
    基于Java+SpringBoot+Vue前后端分离流浪动物管理系统设计和实现
    Windows-Oracle11g 安装详解-含Navicate远程连接配置 -本地监听设置及更换navicate环境指向的oci.dll
    Python基础学习__测试报告
  • 原文地址:https://blog.csdn.net/weiliuhong1/article/details/126881358