📅  最后修改于: 2023-12-03 15:32:05.073000             🧑  作者: Mango
在处理数组时,常常会用到循环移位的操作,即将数组的元素向左或向右移动k个位置。此外,我们还需要将数组分成两半,并使用按位或操作查找数组和。下面是Java代码示例。
循环移位是指将数组的元素向左或向右移动k个位置,并将超出数组长度的元素移动到数组的首尾部分。下面是Java代码示例:
public static void rotate(int[] nums, int k) {
k %= nums.length;
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
public static void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
在上述代码中,我们首先计算出k对数组长度的余数,以避免进行不必要的移位。接着,我们将数组分为前后两个部分,调用reverse方法进行翻转操作,最后再将两个部分合并即可。
我们需要将数组分成两部分,并使用按位或操作查找数组和。下面是Java代码示例:
public static int sumSubarrayMins(int[] A) {
Stack<Pair<Integer, Integer>> s = new Stack<>();
int[] left = new int[A.length];
int[] right = new int[A.length];
// 求左边第一个小于当前元素的位置
for (int i = 0; i < A.length; i++) {
int count = 1;
while (!s.isEmpty() && s.peek().getKey() > A[i]) {
count += s.pop().getValue();
}
s.push(new Pair<>(A[i], count));
left[i] = count;
}
// 求右边第一个小于当前元素的位置
s.clear();
for (int i = A.length - 1; i >= 0; i--) {
int count = 1;
while (!s.isEmpty() && s.peek().getKey() >= A[i]) {
count += s.pop().getValue();
}
s.push(new Pair<>(A[i], count));
right[i] = count;
}
// 按位或操作求和
long ans = 0;
int MOD = 1000000007;
for (int i = 0; i < A.length; i++) {
ans = (ans + (long) A[i] * left[i] * right[i]) % MOD;
}
return (int) ans;
}
在上述代码中,我们使用了栈来保存每个元素的值和出现次数。在计算左边小于当前元素的最近位置时,我们向前遍历数组,如果栈中元素的值大于当前元素,则将这些元素出栈并累加出栈元素的出现次数。然后将当前元素和次数加入栈中,并将次数赋值给左边数组中对应的元素。同样的,我们也可以计算出右边数组每个元素左边小于该元素的最近位置,然后将左右数组对应元素值按位或操作,并累加起来即可。
循环移位代码片段:
public static void rotate(int[] nums, int k) {
k %= nums.length;
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
public static void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
分割数组并使用按位或操作查找数组和代码片段:
public static int sumSubarrayMins(int[] A) {
Stack<Pair<Integer, Integer>> s = new Stack<>();
int[] left = new int[A.length];
int[] right = new int[A.length];
// 求左边第一个小于当前元素的位置
for (int i = 0; i < A.length; i++) {
int count = 1;
while (!s.isEmpty() && s.peek().getKey() > A[i]) {
count += s.pop().getValue();
}
s.push(new Pair<>(A[i], count));
left[i] = count;
}
// 求右边第一个小于当前元素的位置
s.clear();
for (int i = A.length - 1; i >= 0; i--) {
int count = 1;
while (!s.isEmpty() && s.peek().getKey() >= A[i]) {
count += s.pop().getValue();
}
s.push(new Pair<>(A[i], count));
right[i] = count;
}
// 按位或操作求和
long ans = 0;
int MOD = 1000000007;
for (int i = 0; i < A.length; i++) {
ans = (ans + (long) A[i] * left[i] * right[i]) % MOD;
}
return (int) ans;
}