写点什么

2025-01-08:找到按位或最接近 K 的子数组。用 go 语言,给定一个数组 nums 和一个整数 k,你的目标是找到一个子数组,使得该子数组中所有元素进行按位或运算后的结果与 k 之间的绝对差值尽

  • 2025-01-08
    北京
  • 本文字数:3762 字

    阅读完需:约 12 分钟

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 main
import ( "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.MaxInt for 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 := 0 for 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 := 3 result := 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 integersint 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++; } }
// Sort for (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 math
def minimum_difference(nums, k): n = len(nums) bits_max_pos = [-1] * 31
res = math.inf for i in range(n): for j in range(31): if nums[i] >> j & 1 == 1: bits_max_pos[j] = i
pos_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 = 0 j = 0 p = 0 while j < len(pos_to_bit): p = j while j < len(pos_to_bit) and pos_to_bit[j][0] == pos_to_bit[p][0]: val |= 1 << pos_to_bit[j][1] j += 1 res = min(res, abs(val - k))
return res
if __name__ == "__main__": nums = [1, 2, 4, 5] k = 3 result = minimum_difference(nums, k) print(result)
复制代码



发布于: 刚刚阅读数: 3
用户头像

公众号:福大大架构师每日一题 2021-02-15 加入

公众号:福大大架构师每日一题

评论

发布
暂无评论
2025-01-08:找到按位或最接近 K 的子数组。用go语言,给定一个数组 nums 和一个整数 k,你的目标是找到一个子数组,使得该子数组中所有元素进行按位或运算后的结果与 k 之间的绝对差值尽_福大大架构师每日一题_福大大架构师每日一题_InfoQ写作社区