📅  最后修改于: 2023-12-03 15:12:43.018000             🧑  作者: Mango
这是一道GATE-CS-2016考试中的问题14,考察的是计算机科学专业的学生的知识深度和能力。
有两个全局数组 s 和 t,长度分别为 n 和 m。有一个2维数组 shift,其中shift[i] = [direction, amount] 表示 s 的前 i 个元素将按方向(向左或向右)移动 amount 个位置。即,shift[i][0] = 0 表示向左移动,shift[i][0] = 1 表示向右移动。
返回在执行所有shifts后,t 是否仍然等于 s。
输入:
s = [1,2,3,4,5], t = [3,4,5,1,2]
shift = [[0,1],[1,2]]
输出: true
解释:
因为以下操作后 t 变成了 s:
shift[0] = [0,1] :数字序列变为 [2,3,4,5,1].
shift[1] = [1,2] :数字序列变为 [2,3,4,1,5].
s 和 t 未发生改变,所以返回true。
你需要完成函数bool canShifted(int[] s, int[] t, int[][] shift) 的实现。
其中:
s.length, t.length <= 100; shift.length <= 100; shift[i].length == 2; 0 <= shift[i][0] <= 1; 0 <= shift[i][1] <= 100; 这个问题可以用模拟的方式解决,但是还有更高效的方法吗?
为了避免不必要的数组操作,我们可以考虑将 shift[i] 转化成 shift[0] 和 shift[1] 分别表示向左和向右的移动量(shift[i][0] = 0 表示左移,shift[i][0] = 1 表示右移)。然后我们可以遍历 shift[],计算偏移量 left 和 right。最终,判断 t 是否等于 s 的循环移位结果即可。
下面是实现方案的代码片段(Java语言):
public boolean canShifted(int[] s, int[] t, int[][] shift) {
int left = 0, right = 0;
for (int i = 0; i < shift.length; i++) {
if (shift[i][0] == 0) {
left += shift[i][1];
} else {
right += shift[i][1];
}
}
int len = s.length;
right = right % len;
left = left % len;
if (left + right > len) {
left = left + right - len;
right = len - left;
left = len - right - left;
}
int[] s_shifted = new int[len];
for (int i = 0; i < len; i++) {
if (i + left >= len) {
s_shifted[i + left - len] = s[i];
} else {
s_shifted[i + left] = s[i];
}
}
for (int i = 0; i < len; i++) {
if (s_shifted[i] != t[i]) {
return false;
}
}
return true;
}
代码中,我们先计算出数组 s 需要向左或向右移动的量,然后将其转化为最终左移与右移的量。接着创建一个新的数组 s_shifted,将 s 中的元素按偏移量从前往后排列。最后比较两个数组元素是否相等。