2025-01-08:找到按位或最接近 K 的子数组。用go语言,给定一个数组 nums 和一个整数 k,你的目标是找到一个子数组,使得该子数组中所有元素进行按位或运算后的结果与 k 之间的绝对差值尽量小。
具体地,你需要确定一个子数组 nums[l..r],使得以下表达式的值最小化:
|k - (nums[l] OR nums[l + 1] ... OR nums[r])|
最后,返回这个最小绝对差值。
这里所说的子数组指的是数组中连续的非空元素序列。
1 <= nums.length <= 100000。
1 <= nums[i] <= 1000000000。
1 <= k <= 1000000000。
输入:nums = [1,2,4,5], k = 3。
输出:0。
解释:
子数组 nums[0..1] 的按位 OR 运算值为 3 ,得到最小差值 |3 - 3| = 0 。
答案2025-01-08:
chatgpt
题目来自leetcode3171。
大体步骤如下:
1.初始化 bitsMaxPos
数组,用于记录每个元素在每位上的最大位置,初始值为 -1。
2.初始化结果 res
为整数最大值 math.MaxInt
。
3.遍历数组 nums
:
a. 对于每个元素,记录其在 bitsMaxPos
数组中每位上的位置,即进行按位运算并更新 bitsMaxPos
。
b. 构建二维数组 posToBit
,记录每个位的最大位置和该位的值。
c. 按照每位最大位置倒序排序 posToBit
数组。
d. 遍历 posToBit
数组,计算包含当前位的所有可能组合的按位或值,更新结果 res
。
4.最终返回 res
作为最小绝对差值。
总体而言,这个算法的时间复杂度取决于数组长度 n
,其中对数组进行了遍历和排序操作。
额外空间复杂度主要取决于辅助数组的大小和额外变量的空间开销,约为 O(n)。
Go完整代码如下:
package mainimport ("fmt""sort""math"
)func minimumDifference(nums []int, k int) int {n := len(nums)bitsMaxPos := make([]int, 31)for i := range bitsMaxPos {bitsMaxPos[i] = -1}res := math.MaxIntfor i := 0; i < n; i++ {for j := 0; j <= 30; j++ {if nums[i]>>j & 1 == 1 {bitsMaxPos[j] = i}}posToBit := make([][2]int, 0)for j := 0; j <= 30; j++ {if bitsMaxPos[j] != -1 {posToBit = append(posToBit, [2]int{bitsMaxPos[j], j})}}sort.Slice(posToBit, func(a, b int) bool {return posToBit[a][0] > posToBit[b][0]})val := 0for j, p := 0, 0; j < len(posToBit); p = j {for j < len(posToBit) && posToBit[j][0] == posToBit[p][0] {val |= 1 << posToBit[j][1]j++}res = min(res, int(math.Abs(float64(val - k))))}}return res
}func main() {nums := []int{1,2,4,5}k := 3result := minimumDifference(nums,k)fmt.Println(result)
}
Rust完整代码如下:
use std::cmp;
use std::collections::HashSet;fn minimum_difference(nums: Vec<i32>, k: i32) -> i32 {let n = nums.len();let mut bits_max_pos = [-1; 31];let mut res = i32::MAX;for i in 0..n {for j in 0..=30 {if nums[i] >> j & 1 == 1 {bits_max_pos[j] = i as i32;}}let mut pos_to_bit: Vec<(i32, i32)> = Vec::new();for j in 0..=30 {if bits_max_pos[j] != -1 {pos_to_bit.push((bits_max_pos[j], j as i32));}}pos_to_bit.sort_by(|a, b| b.0.cmp(&a.0));let mut val = 0;let mut j = 0;let mut p = 0;while j < pos_to_bit.len() {p = j;while j < pos_to_bit.len() && pos_to_bit[j].0 == pos_to_bit[p].0 {val |= 1 << pos_to_bit[j].1;j += 1;}res = cmp::min(res, (val - k).abs() as i32);}}res
}fn main() {let nums = vec![1, 2, 4, 5];let k = 3;let result = minimum_difference(nums, k);println!("{}", result);
}
C完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>// Helper function to find the minimum of two integers
int min(int a, int b) {return (a < b) ? a : b;
}int minimumDifference(int nums[], int size, int k) {int bitsMaxPos[31];for (int i = 0; i < 31; i++) {bitsMaxPos[i] = -1;}int res = INT_MAX;for (int i = 0; i < size; i++) {for (int j = 0; j <= 30; j++) {if ((nums[i] >> j) & 1 == 1) {bitsMaxPos[j] = i;}}int posToBit[size][2];int count = 0;for (int j = 0; j <= 30; j++) {if (bitsMaxPos[j] != -1) {posToBit[count][0] = bitsMaxPos[j];posToBit[count][1] = j;count++;}}// Sortfor (int a = 0; a < count; a++) {for (int b = a+1; b < count; b++) {if (posToBit[a][0] < posToBit[b][0]) {int temp0 = posToBit[a][0];int temp1 = posToBit[a][1];posToBit[a][0] = posToBit[b][0];posToBit[a][1] = posToBit[b][1];posToBit[b][0] = temp0;posToBit[b][1] = temp1;}}}int val = 0;for (int j = 0, p = 0; j < count; p = j) {while (j < count && posToBit[j][0] == posToBit[p][0]) {val |= 1 << posToBit[j][1];j++;}res = min(res, abs(val - k));}}return res;
}int main() {int nums[] = {1, 2, 4, 5};int size = sizeof(nums) / sizeof(nums[0]);int k = 3;int result = minimumDifference(nums, size, k);printf("%d\n", result);return 0;
}
C++完整代码如下:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <climits>int min(int a, int b) {return (a < b) ? a : b;
}int minimumDifference(std::vector<int> nums, int k) {int n = nums.size();std::vector<int> bitsMaxPos(31, -1);int res = INT_MAX;for (int i = 0; i < n; i++) {for (int j = 0; j <= 30; j++) {if ((nums[i] >> j) & 1 == 1) {bitsMaxPos[j] = i;}}std::vector<std::pair<int, int>> posToBit;for (int j = 0; j <= 30; j++) {if (bitsMaxPos[j] != -1) {posToBit.push_back(std::make_pair(bitsMaxPos[j], j));}}std::sort(posToBit.begin(), posToBit.end(), [](const std::pair<int, int>& a, const std::pair<int, int>& b) {return a.first > b.first;});int val = 0;for (int j = 0, p = 0; j < posToBit.size(); p = j) {while (j < posToBit.size() && posToBit[j].first == posToBit[p].first) {val |= 1 << posToBit[j].second;j++;}res = min(res, std::abs(val - k));}}return res;
}int main() {std::vector<int> nums = {1, 2, 4, 5};int k = 3;int result = minimumDifference(nums, k);std::cout << result << std::endl;return 0;
}
Python完整代码如下:
# -*-coding:utf-8-*-import mathdef minimum_difference(nums, k):n = len(nums)bits_max_pos = [-1] * 31res = math.inffor i in range(n):for j in range(31):if nums[i] >> j & 1 == 1:bits_max_pos[j] = ipos_to_bit = []for j in range(31):if bits_max_pos[j] != -1:pos_to_bit.append((bits_max_pos[j], j))pos_to_bit.sort(key=lambda x: x[0], reverse=True)val = 0j = 0p = 0while j < len(pos_to_bit):p = jwhile j < len(pos_to_bit) and pos_to_bit[j][0] == pos_to_bit[p][0]:val |= 1 << pos_to_bit[j][1]j += 1res = min(res, abs(val - k))return resif __name__ == "__main__":nums = [1, 2, 4, 5]k = 3result = minimum_difference(nums, k)print(result)