一、最大乘积区间问题
问题描述
小R手上有一个长度为 n 的数组 (n > 0),数组中的元素分别来自集合 [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]。小R想从这个数组中选取一段连续的区间,得到可能的最大乘积。
你需要帮助小R找到最大乘积的区间,并输出这个区间的起始位置 x 和结束位置 y (x ≤ y)。如果存在多个区间乘积相同的情况,优先选择 x 更小的区间;如果 x 相同,选择 y 更小的区间。
注意:数组的起始位置为 1,结束位置为 n。
测试样例
样例1:
输入:
n = 5, arr = [1, 2, 4, 0, 8]
输出:[1, 3]
样例2:
输入:
n = 7, arr = [1, 2, 4, 8, 0, 256, 0]
输出:[6, 6]
样例3:
输入:
n = 8, arr = [1, 2, 4, 8, 0, 256, 512, 0]
输出:[6, 7]
解题思路:
问题理解
我们需要从一个数组中找到一段连续的区间,使得这段区间的乘积最大。数组中的元素只包含 [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] 这些值。
关键点
- 乘积的计算:由于数组中的元素都是2的幂次,乘积的计算相对简单,但需要注意乘积可能会非常大,因此需要考虑溢出问题。
- 0的处理:0乘以任何数都为0,因此如果区间中包含0,那么这个区间的乘积就是0。
- 区间的选择:如果存在多个区间乘积相同的情况,优先选择
x更小的区间;如果x相同,选择y更小的区间。
数据结构与算法
- 遍历数组:我们可以通过遍历数组来计算每个可能的区间的乘积。
- 动态规划:可以使用动态规划的思想来记录当前区间的乘积,并根据当前元素是否为0来决定是否重置区间。
- 记录最大乘积:在遍历过程中,记录最大乘积及其对应的区间。
最终代码:
def solution(n, data):
max_product = 0
best_start = -1
best_end = -1
# 遍历数组,尝试所有可能的区间
for start in range(n):
current_product = 1
for end in range(start, n):
# 计算当前区间的乘积
current_product *= data[end]
# 如果乘积为0,跳过这个区间
if current_product == 0:
break
# 如果当前乘积大于最大乘积,更新最大乘积和区间
if current_product > max_product:
max_product = current_product
best_start = start
best_end = end
# 如果乘积相等,选择更小的区间
elif current_product == max_product:
if start < best_start or (start == best_start and end < best_end):
best_start = start
best_end = end
# 返回区间的起始和结束位置
return [best_start + 1, best_end + 1]
if __name__ == "__main__":
# Add your test cases here
print(solution(5, [1, 2, 4, 0, 8]) == [1, 3])
print(solution(7, [1, 2, 4, 8, 0, 256, 0]) == [6, 6])
运行结果:

二、时尚圈的衣着稳定性问题
问题描述
小U在时尚圈组织了一场“校服日”活动,有 n 名学生围成一圈参加活动。每位学生都穿着白色或黑色的校服,白色用 0 表示,黑色用 1 表示。每一天,如果某个学生发现自己和相邻的两位学生穿着相同颜色的校服,那么他会在第二天更换成另一种颜色的校服;否则,他会保持不变。
你的任务是帮助小U判断,在第几天学生们的穿着会达到稳定状态——即某一天后,所有学生的穿着不再发生任何变化。同时,你还需要计算在稳定后,有多少学生的校服颜色与其相邻的同学不同,这些学生被称为“时尚达人”。
最终你需要返回一个包含两个元素的数组:
- 第一个数字表示稳定下来的天数。如果永远无法稳定,则输出
-1。 - 第二个数字表示稳定后成为“时尚达人”的学生人数。如果永远无法稳定,则输出
-1。
测试样例
样例1:
输入:
n = 4 ,data = "0000"
输出:[-1, -1]
样例2:
输入:
n = 4 ,data = "1110"
输出:[2, 4]
样例3:
输入:
n = 6 ,data = "010101"
输出:[1, 6]
解题思路:
问题理解
- 学生座位排列:学生围成一个圈,这意味着第1个学生和第n个学生是相邻的。
- 校服颜色变化规则:如果一个学生发现相邻的两个学生穿的衣服都跟他一样,则他会在第二天换成另一个颜色的校服,否则保持不变。
- 稳定状态:当某一天所有学生的校服颜色都不再变化时,系统达到稳定状态。
- 时尚达人:稳定后,与相邻同学穿不同校服的学生被称为“时尚达人”。
数据结构选择
- 字符串:用于表示每一天学生的校服颜色。
- 循环队列:由于学生围成一个圈,可以使用循环队列来处理相邻关系。
算法步骤
-
初始化:读取输入的n和初始校服颜色字符串。
-
模拟每一天的变化:
- 创建一个新的字符串来存储下一天的校服颜色。
- 遍历每个学生,检查其相邻的两个学生是否穿相同颜色的校服。
- 根据规则更新新字符串。
-
检查稳定状态:
- 如果某一天的校服颜色与前一天相同,则达到稳定状态。
- 记录稳定的天数。
-
计算时尚达人:
- 在稳定状态下,统计与相邻同学穿不同校服的学生数量。
最终代码:
#include <iostream>
#include <vector>
#include <string>
std::vector<int> solution(int n, const std::string &data) {
std::vector<int> result = {-1, -1};
std::string tmp = data;
int changes = 0;
int days = 0;
// 初始检查
for (int i = 0; i < n; i++) {
if (i == 0) {
if (tmp[0] == tmp[n - 1] && tmp[0] == tmp[1]) {
changes++;
}
} else if (i == n - 1) {
if (tmp[n - 1] == tmp[n - 2] && tmp[n - 1] == tmp[0]) {
changes++;
}
} else {
if (tmp[i] == tmp[i + 1] && tmp[i] == tmp[i - 1]) {
changes++;
}
}
}
if (changes == n) {
return result;
}
days++;
while (changes != 0) {
changes = 0;
std::string k = tmp;
for (int i = 0; i < n; i++) {
if (i == 0) {
if (tmp[0] == tmp[n - 1] && tmp[0] == tmp[1]) {
k[0] = (tmp[0] == '0') ? '1' : '0';
}
} else if (i == n - 1) {
if (tmp[n - 1] == tmp[n - 2] && tmp[n - 1] == tmp[0]) {
k[n - 1] = (tmp[n - 1] == '0') ? '1' : '0';
}
} else {
if (tmp[i] == tmp[i + 1] && tmp[i] == tmp[i - 1]) {
k[i] = (tmp[i] == '0') ? '1' : '0';
}
}
}
tmp = k;
days++;
for (int i = 0; i < n; i++) {
if (i == 0) {
if (tmp[0] == tmp[n - 1] && tmp[0] == tmp[1]) {
changes++;
}
} else if (i == n - 1) {
if (tmp[n - 1] == tmp[n - 2] && tmp[n - 1] == tmp[0]) {
changes++;
}
} else {
if (tmp[i] == tmp[i + 1] && tmp[i] == tmp[i - 1]) {
changes++;
}
}
}
}
result[1] = 0;
for (int i = 0; i < n; i++) {
if (i == 0) {
if (tmp[0] != tmp[n - 1] && tmp[0] != tmp[1]) {
result[1]++;
}
} else if (i == n - 1) {
if (tmp[n - 1] != tmp[n - 2] && tmp[n - 1] != tmp[0]) {
result[1]++;
}
} else {
if (tmp[i] != tmp[i + 1] && tmp[i] != tmp[i - 1]) {
result[1]++;
}
}
}
result[0] = days;
return result;
}
int main() {
// Add your test cases here
std::cout << solution(21, "001000001101001101110")[0] << std::endl;
return 0;
}
运行结果:
![]()