2022-11-03:给定一个数组arr,和一个正数k
如果arr[i] == 0,表示i这里既可以是左括号也可以是右括号,
而且可以涂上1~k每一种颜色
如果arr[i] != 0,表示i这里已经确定是左括号,颜色就是arr[i]的值
那么arr整体就可以变成某个括号字符串,并且每个括号字符都带有颜色。
返回在括号字符串合法的前提下,有多少种不同的染色方案。
不管是排列、还是颜色,括号字符串任何一点不一样,就算不同的染色方案
最后的结果%10001,为了方便,我们不处理mod,就管核心思路。
2 <= arr长度 <= 5000
1 <= k <= 1000
0 <= arr[i] <= k。
2022.8.7笔试第三道。来自猿辅导。

答案2022-11-03:

递归或者动态规划。

代码用rust编写。代码如下:

  1. use std::iter::repeat;
  2. use rand::Rng;
  3. fn main() {
  4. let nn: i32 = 5;
  5. let kk: i32 = 4;
  6. let test_time: i32 = 1000;
  7. println!("测试开始");
  8. for _i in 0..test_time {
  9. let n = (rand::thread_rng().gen_range(0, nn) + 1) << 1;
  10. let k = rand::thread_rng().gen_range(0, kk) + 1;
  11. let mut arr = random_array(n, k);
  12. let ans1 = ways1(&mut arr, k);
  13. let ans2 = ways2(&mut arr, k);
  14. if ans1 != ans2 {
  15. println!("arr = {:?},k = {}", arr, k);
  16. println!("ans1 = {}", ans1);
  17. println!("ans2 = {}", ans2);
  18. println!("出错了!");
  19. break;
  20. }
  21. }
  22. println!("测试结束");
  23. }
  24. // 暴力方法
  25. // 为了验证
  26. fn ways1(arr: &mut Vec<i32>, k: i32) -> i32 {
  27. if arr.len() & 1 != 0 {
  28. return 0;
  29. }
  30. return process1(arr, 0, k);
  31. }
  32. fn process1(arr: &mut Vec<i32>, index: i32, k: i32) -> i32 {
  33. if index == arr.len() as i32 {
  34. let n = arr.len() as i32;
  35. let mut stack: Vec<i32> = repeat(0).take(n as usize).collect();
  36. let mut size = 0;
  37. for i in 0..n {
  38. if arr[i as usize] > 0 {
  39. stack[size as usize] = arr[i as usize];
  40. size += 1;
  41. } else {
  42. if size == 0 {
  43. return 0;
  44. }
  45. size -= 1;
  46. if stack[size as usize] != -arr[i as usize] {
  47. return 0;
  48. }
  49. }
  50. }
  51. return if size == 0 { 1 } else { 0 };
  52. } else if arr[index as usize] != 0 {
  53. return process1(arr, index + 1, k);
  54. } else {
  55. let mut ans = 0;
  56. for color in 1..=k {
  57. arr[index as usize] = color;
  58. ans += process1(arr, index + 1, k);
  59. arr[index as usize] = -color;
  60. ans += process1(arr, index + 1, k);
  61. arr[index as usize] = 0;
  62. }
  63. return ans;
  64. }
  65. }
  66. fn ways2(arr: &mut Vec<i32>, k: i32) -> i32 {
  67. let n = arr.len() as i32;
  68. if n & 1 != 0 {
  69. return 0;
  70. }
  71. let a = combines(arr);
  72. let mut b = 0;
  73. for num in arr.iter() {
  74. if *num != 0 {
  75. b += 1;
  76. }
  77. }
  78. return if ((n - (b << 1)) >> 1) < 0 {
  79. 0
  80. } else {
  81. a * k.pow(((n - (b << 1)) >> 1) as u32)
  82. };
  83. }
  84. // 忽略染色这件事,求合法的括号结合数量
  85. fn combines(arr: &mut Vec<i32>) -> i32 {
  86. let n = arr.len() as i32;
  87. let mut dp: Vec<Vec<i32>> = repeat(repeat(-1).take(n as usize).collect())
  88. .take(n as usize)
  89. .collect();
  90. return f(arr, 0, 0, &mut dp);
  91. }
  92. // arr[i....]范围上,去做决定
  93. // j : arr[0..i-1]已经做完决定的部分,左括号比右括号,多几个
  94. // 返回:
  95. // arr[i....]范围上,去做决定,
  96. // 已经做完决定的部分,左括号比右括号多j个
  97. // 这样的情况下,最终合法的括号结合,多少个!
  98. // process(arr, 0, 0)
  99. fn process(arr: &mut Vec<i32>, i: i32, j: i32) -> i32 {
  100. if i == arr.len() as i32 {
  101. return if j == 0 { 1 } else { 0 };
  102. }
  103. if j < 0 {
  104. return 0;
  105. }
  106. // 这个不写也行
  107. // 锦上添花的剪枝条件
  108. if arr.len() as i32 - i < j {
  109. return 0;
  110. }
  111. // arr[i] != 0
  112. if arr[i as usize] != 0 {
  113. // (
  114. return process(arr, i + 1, j + 1);
  115. } else {
  116. // arr[i] 0 ? ( )
  117. let p1 = process(arr, i + 1, j + 1);
  118. let p2 = process(arr, i + 1, j - 1);
  119. return p1 + p2;
  120. }
  121. }
  122. // 在arr[i...]范围上做决定
  123. // 之前在arr[0...i-1]上的决定,使得左括号比右括号多了j个
  124. // 最终合法的括号结合是多少
  125. fn f(arr: &mut Vec<i32>, i: i32, j: i32, dp: &mut Vec<Vec<i32>>) -> i32 {
  126. let n = arr.len() as i32;
  127. if i == n {
  128. return if j == 0 { 1 } else { 0 };
  129. }
  130. if j < 0 {
  131. return 0;
  132. }
  133. if n - i < j {
  134. return 0;
  135. }
  136. // 如果缓存命中,直接返回答案
  137. if dp[i as usize][j as usize] != -1 {
  138. return dp[i as usize][j as usize];
  139. }
  140. let mut ans = 0;
  141. if arr[i as usize] > 0 {
  142. ans = f(arr, i + 1, j + 1, dp);
  143. } else {
  144. ans = f(arr, i + 1, j + 1, dp) + f(arr, i + 1, j - 1, dp);
  145. }
  146. dp[i as usize][j as usize] = ans;
  147. return ans;
  148. }
  149. // 生成长度随机的数组
  150. // 值在0~K之间,但是50%的概率值是0,50%的概率值是1~k中的一个
  151. fn random_array(n: i32, k: i32) -> Vec<i32> {
  152. let mut ans = vec![];
  153. for _ in 0..n {
  154. ans.push(if rand::thread_rng().gen_range(0, 2) == 0 {
  155. 0
  156. } else {
  157. rand::thread_rng().gen_range(0, k) + 1
  158. })
  159. }
  160. return ans;
  161. }

执行结果如下:


左神java代码

2022-11-03:给定一个数组arr,和一个正数k 如果arr[i] == 0,表示i这里既可以是左括号也可以是右括号, 而且可以涂上1~k每一种颜色 如果arr[i] != 0,表示i这里已经确的更多相关文章

  1. 七、如何在Java中高效检查一个数组是否含有一个值

    如何检查一个数组(非排序的)是否包含特定的值.这是个非常有用或经常被在Java中使用.这是个在Stack Overflow中高得票的问题.在已经高得票的答案中,有许多不同的处理方法,但是时间的复杂度非 ...

  2. js判断一个数组是否包含一个指定的值

    今天看了一下  有好几种方法  总结一下 1:array.indexOf   此方法判断数组中是否存在某个值,如果存在返回数组元素的下标,否则返回-1 let arr = ['something', ...

  3. [转]php判断一个数组是另一个数组的子集

    FROM : http://blog.csdn.net/lcion/article/details/8985220 今天完成一个算法的过程中,有几个需求模块,其中就有判断$a数组是否是$b数组的子集, ...

  4. php判断一个数组是另一个数组的子集

    需求最少的时间复杂度判断$a数组是否是$b数组的子集 // 快速的判断$a数组是否是$b数组的子集$a = array(135,138);$b = array(135,138,137); 实现方法 这 ...

  5. MATLAB一个数组中另一个数组的值

    c = setdiff(a,b) 删掉素组a中数组b的元素 如:

  6. includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。

    注意:对象数组不能使用includes方法来检测. JavaScript Demo: Array.includes() var array1 = [1, 2, 3]; console.log(arra ...

  7. php让一个数组按照另外一个数组的键名进行排序

    $a = [ 'id', 'name', 'identityId', 'phone', 'email', 'schoolId' ]; $b = [ 'id' => '唯一标识', 'identi ...

  8. 判断一个数组是否包含一个指定的值 includes-ES6

    var array1 = [1, 2, 3]; console.log(array1.includes(2));  // trueconsole.log(array1.includes(2, 5)); ...

  9. Java 将两个有序数组合成为一个有序数组

    基本思路 1.如果其中一个数组的元素均大于另一个数组的元素,则可以直接组合,不用拆分. 即:其中一个数组的第一个元素大于或者小于另一个数组的最后一个元素 2.若不满足1中的情况,则表明数组需要拆分,拆 ...

  10. java二分法来求一个数组中一个值的key

    package TestArray; import java.util.Arrays; /** * 二分法查找 */ public class Test { public static void ma ...

随机推荐

  1. [ABC284F] ABCBAC(字符串哈希)

    思路 这里我们要注意以下几点: 字符串哈希自然溢出(\(\pmod 2^64\))会被卡,会\(WA~5\)个点 注意有模数的时候不要用\(unsigned\ long \ long\)类型 代码 # ...

  2. Kubecost - Kubernetes 开支监控和管理

    ️URL: https://www.kubecost.com/ Description: Kubeccost 为使用 Kubernetes 的团队提供实时成本可视化和洞察,帮助您持续降低云成本. 昨天 ...

  3. Agora 教程丨如何实现15mins自主搭建一个教育平台?

    [ 前言 ] 2020 年对于全球而言都是非常特殊的一年,人与人之间的"物理连结"受到了严重影响,日常的生活.工作大都也逐渐向线上转移.受此影响,大量的线下业务也加速了线上转型,这 ...

  4. SpringBoot——模板引擎及原理

    更多内容,前往IT-BLOG 一.模板引擎的思想 模板是为了将显示与数据分离,模板技术多种多样,但其本质都是将模板文件和数据通过模板引擎生成最终的 HTML代码. 二.SpringBoot模板引擎 S ...

  5. Condition 接口

    系统性学习,移步IT-BLOG Java 对象拥有一组监视方法:wait().wait(long timeout).notify() 以及 notifyAll() 方法,这些方法与 synchroni ...

  6. 单元测试Mockito框架

    单元测试Mockito框架 Mock 测试就是在测试过程中,对于某些 不容易构造(如 HttpServletRequest 必须在 Servlet 容器中才能构造出来)或者不容易获取 比较复杂 的对象 ...

  7. el-tree组件过来吧默认打开全部子节点

    //搜索到节点必须打开此节点所有子节点,因为默认是不会打开子节点的,所以手动设置打开的最高层级.本次我设置了最大四个层级 filterNode(value,data,node) { if(!value ...

  8. [Java SE]Java版本特性解读:java.util.Optional [JDK1.8-]

    1 概述 本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空(null/empty). Optional 是 Java 实现函数式编程的强劲一步,并且帮助在范 ...

  9. [网络]公共网络安全漏洞库: CVE / CNCVE

    本文博主的经历与该博文处理绿盟科技安全评估的系统漏洞 - 博客园的经历相同: 处理[第三方网络安全公司]给[公司产品]的[客户的服务器]扫描后生成的[安全漏洞报告]. 1 前言 以网络安全行业中最大的 ...

  10. 如何在2023年学习React

    在2023年学习React并不是一件容易的事情.自2019年React Hooks发布以来,我们已经拥有了很多稳定性,但现在形势正在再次变化.而这次变化可能比使用React Hooks时更加不稳定.在 ...