- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试用字符串解决一个非常复杂的问题:
Given 是一个最多包含 100000 个字符的字符串,仅由两个不同的字符“L”和“R”组成。序列“RL”被认为是“坏的”,必须通过应用交换来减少这种发生。
然而,字符串被认为是循环的,所以即使字符串 'LLLRRR' 也有一个由最后一个 'R' 和第一个 'L' 形成的 'RL' 序列。
可以交换两个连续元素。所以我们只能交换位置 i 和 i+1 上的元素,或者位置 0 和 n-1 上的元素,如果 n 是字符串的长度(字符串是 0 索引的)。
目标是找到在字符串中只留下一个坏连接所需的最少交换次数。
例子
对于字符串 'RLLRRL',这个问题可以通过一个交换来解决:交换第一个和最后一个字符(因为字符串是循环的)。因此,该字符串将变为 'LLLRRR',并带有一个错误连接。
我试过的
我的想法是使用动态规划,并计算任何给定的“L”需要多少次交换才能将所有其他“L”放在“L”的左侧,或者放在“L”的右侧。对于任何'R',我计算相同。
这个算法在 O(N) 时间内工作,但它没有给出正确的结果。
当我必须交换第一个和最后一个元素时,它不起作用。我应该在我的算法中添加什么以使其也适用于这些交换?
最佳答案
该问题可以在线性时间内解决。
一些观察和定义:
.
而不是 L
所以它更容易阅读:RRR...RR....
RRR
, ...
, RR
和 ....
.假设您想将上面字符串中的两个“R”组与左侧的“R”组连接起来。然后,您可以通过执行 6 次交换,向左“移动”3 个步骤的中间组:RRR...RR....
RRR..R.R....
RRR..RR.....
RRR.R.R.....
RRR.RR......
RRRR.R......
RRRRR.......
function minimumSwaps(s) {
var groups, start, n, i, minCost, halfSpace, splitAt, space,
cost, costLeft, costRight, distLeft, distRight, itemsLeft, itemsRight;
// 1. Get group sizes
groups = [];
start = 0;
for (i = 1; i < s.length; i++) {
if (s[i] != s[start]) {
groups.push(i - start);
start = i;
}
}
// ... exit when the number of groups is already optimal
if (groups.length <= 2) return 0; // zero swaps
// ... the number of groups should be even (because of circle)
if (groups.length % 2 == 1) { // last character not same as first
groups.push(s.length - start);
} else { // Ends are connected: add to the length of first group
groups[0] += s.length - start;
}
n = groups.length;
// 2. Get the parameters of the scenario where group 0 is the middle:
// i.e. the members of group 0 do not move in that case.
// Get sum of odd groups, which we consider as "space", while even
// groups are considered items to be moved.
halfSpace = 0;
for (i = 1; i < n; i+=2) {
halfSpace += groups[i];
}
halfSpace /= 2;
// Get split-point between what is "left" from the "middle"
// and what is "right" from it:
space = 0;
for (i = 1; space < halfSpace; i+=2) {
space += groups[i];
}
splitAt = i-2;
// Get sum of items, and cost, to the right of group 0
itemsRight = distRight = costRight = 0;
for (i = 2; i < splitAt; i+=2) {
distRight += groups[i-1];
itemsRight += groups[i];
costRight += groups[i] * distRight;
}
// Get sum of items, and cost, to the left of group 0
itemsLeft = distLeft = costLeft = 0;
for (i = n-2; i > splitAt; i-=2) {
distLeft += groups[i+1];
itemsLeft += groups[i];
costLeft += groups[i] * distLeft;
}
cost = costLeft + costRight;
minCost = cost;
// 3. Translate the cost parameters by incremental changes for
// where the mid-point is set to the next even group
for (i = 2; i < n; i += 2) {
distLeft += groups[i-1];
itemsLeft += groups[i-2];
costLeft += itemsLeft * groups[i-1];
costRight -= itemsRight * groups[i-1];
itemsRight -= groups[i];
distRight -= groups[i-1];
// See if we need to change the split point. Items that get
// at the different side of the split point represent items
// that have a shorter route via the other half of the circle.
while (distLeft >= halfSpace) {
costLeft -= groups[(splitAt+1)%n] * distLeft;
distLeft -= groups[(splitAt+2)%n];
itemsLeft -= groups[(splitAt+1)%n];
itemsRight += groups[(splitAt+1)%n];
distRight += groups[splitAt];
costRight += groups[(splitAt+1)%n] * distRight;
splitAt = (splitAt+2)%n;
}
cost = costLeft + costRight;
if (cost < minCost) minCost = cost;
}
return minCost;
}
function validate(s) {
return new Set(s).size <= 2; // maximum 2 different letters used
}
// I/O
inp.oninput = function () {
var s, result, start;
s = inp.value;
start = performance.now(); // get timing
if (validate(s)) {
result = minimumSwaps(s); // apply algorithm
} else {
result = 'Please use only 2 different characters';
}
outp.textContent = result;
ms.textContent = Math.round(performance.now() - start);
}
rnd.onclick = function () {
inp.value = Array.from(Array(100000), _ =>
Math.random() < 0.5 ? "L" : "R").join('');
if (inp.value.length != 100000) alert('Your browser truncated the input!');
inp.oninput(); // trigger input handler
}
inp.oninput(); // trigger input handler
input { width: 100% }
<p>
<b>Enter LR series:</b>
<input id="inp" value="RLLRRL"><br>
<button id="rnd">Produce random of size 100000</button>
</p><p>
<b>Number of swaps: </b><span id="outp"></span><br>
<b>Time used: </b><span id="ms"></span>ms
</p>
关于string - 计算最小交换次数以对字符串中的字符进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43820357/
SQL 和一般开发的新手,我有一个表(COUNTRIES),其中包含字段(INDEX、NAME、POPULATION、AREA) 通常我添加一个客户端(Delphi)计算字段(DENSITY)和 On
我想使用 calc(100%-100px),但在我的 demo 中不起作用由于高度只接受像素,因此如何将此百分比值转换为像素。 最佳答案 以下将为您提供高度: $(window).height();
我正在尝试在 MySQL 中添加列并动态填充其他列。 例如我有一张表“数字”并具有第 1 列、第 2 列、第 3 列,这些总数应填充在第 4 列中 最佳答案 除非我误解了你的问题,否则你不只是在寻找:
我想返回简单计算的结果,但我不确定如何执行此操作。我的表格如下: SELECT COUNT(fb.engineer_id) AS `total_feedback`, SUM(fb.ra
我一直在尝试做这个程序,但我被卡住了,我仍然是一个初学者,任何帮助将不胜感激。我需要程序来做 打印一个 10 X 10 的表格,其中表格中的每个条目都是行号和列号的总和 包含一个累加器,用于计算所有表
这个计算背后一定有一些逻辑。但我无法得到它。普通数学不会导致这种行为。谁能帮我解释一下原因 printf ("float %f\n", 2/7 * 100.0); 结果打印 1.000000 为什么会
我想计算从 0 到 (n)^{1/2} - 1 的数字的 AND每个数字从 0 到 (n)^{1/2} - 1 .我想在 O(n) 中执行此操作时间,不能使用 XOR、OR、AND 运算。 具体来说,
如何在 Excel 中将公式放入自定义数字格式?例如(出于说明目的随机示例), 假设我有以下数据: 输入 输出 在不编辑单元格中的实际数据的情况下,我想显示单元格中的值除以 2,并保留两位小数: 有没
每次我在 Flutter 应用程序中调用计算()时,我都会看到内存泄漏,据我所知,这基本上只是一种生成隔离的便捷方法。我的应用程序内存占用增加并且在 GC 之后永远不会减少。 我已将我的代码简化为仅调
我有数字特征观察 V1通过 V12用于目标变量 Wavelength .我想计算 Vx 之间的 RMSE列。数据格式如下。 每个变量“Vx”以 5 分钟的间隔进行测量。我想计算所有 Vx 变量的观测值
我正在寻找一种使用 C 语言计算文件中未知字符数的简单方法。谢谢你的帮助 最佳答案 POSIX 方式(可能是您想要的方式): off_t get_file_length( FILE *file ) {
我正在使用 Postgres,并且我正试图围绕如何在连续日期跨度中得出第一个开始日期的问题进行思考。例如 :- ID | Start Date | End Date =================
我有一个订单表格,我在其中使用 jQuery 计算插件来汇总总数。 此求和工作正常,但生成的“总和”存在问题。总之,我希望用逗号替换任何点。 代码的基础是; function ($this) {
我在使用 double 变量计算简单算术方程时遇到问题。 我有一个具有 double 属性 Value 的组件,我将此属性设置为 100。 然后我做一个简单的减法来检查这个值是否真的是 100: va
我在这里看到了一些关于 CRC 32 计算的其他问题。但没有一个让我满意,因此是这样。 openssl 库是否有任何用于计算 CRC32 的 api 支持?我已经在为 SHA1 使用 openssl,
当我在PHP日期计算中遇到问题时,我感到惊讶。 $add = '- 30 days'; echo date('Y-m-01', strtotime($add)); // result is 2017-
我正在使用 javascript 进行练习,我编写了这个脚本来计算 2 个变量的总和,然后在第三个方程中使用这个总和!关于如何完成这项工作的任何想法都将非常有用! First Number:
我有一个来自EAC的提示单和一个包含完整专辑的FLAC文件。 我正在尝试制作一些python脚本来播放文件,因为我需要能够设置在flac文件中开始的位置。 如何从CueSheet格式MM:SS:FF转
这个问题已经有答案了: Adding two numbers concatenates them instead of calculating the sum (24 个回答) 已关闭去年。 我有一个
4000 我需要上面字段 name="quantity" 和 id="price" 中的值,并使用 javascript 函数进行计算,并将其显示在字段 id= 中仅当我单击计算按钮时才显示“总
我是一名优秀的程序员,十分优秀!