2025-01-08:找到按位或最接近 K 的子数组。用go语言,给定一个数组 nums 和一个整数 k,你的目标是找到一个子数组,使得该子数组中所有元素进行按位或运算后的结果与 k 之间的绝对差值尽
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:
题目来自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 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++;
}
}
// 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)

2025-01-08:找到按位或最接近 K 的子数组。用go语言,给定一个数组 nums 和一个整数 k,你的目标是找到一个子数组,使得该子数组中所有元素进行按位或运算后的结果与 k 之间的绝对差值尽的更多相关文章
- smoj2828子数组有主元素
题面 一个数组B,如果有其中一个元素出现的次数大于length(B) div 2,那么该元素就是数组B的主元素,显然数组B最多只有1个主元素,因为数组B有主元素,所以被称为"优美的" ...
- 剑指Offer-连续子数组中的最大和
题目 输入一个整型数组,数组里有正数也有负数.数组中的一个或连续多个整数组成一个子数组.求所有子数组的和的最大值.要求时间复杂度为 O(n). 输入 [1,-2,3,10,-4,7,2,-5] 返回值 ...
- Java算法-求最大和的子数组序列
问题:有一个连续数组,长度是确定的,它包含多个子数组,子数组中的内容必须是原数组内容中的一个连续片段,长度不唯一,子数组中每个元素相加的结果称为子数组的和,现要求找出和最大的一个子数组. 具体算法如下 ...
- LeetCode-2104 子数组范围和
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/sum-of-subarray-ranges 题目描述 给你一个整数数组 nums .nums 中 ...
- 实现子数组和绝对值差最小 - Objective-C
类似于背包问题,前提条件是数组全是正整数和0,先求和Sum,再从子数组中找出接近Sum/2的子数组 @interface TempState : NSObject @property (nonatom ...
- N元数组的子数组之和的最大值
题目:有N个整数的元素的一维数组,求子数组中元素之和中最大的一组(思想:动态规划) 分析: 设该数组为array[N], 那么对于array[i]该不该在元素之和最大的那个子数组中呢?首先,不如假设a ...
- [LeetCode] Maximum Average Subarray II 子数组的最大平均值之二
Given an array consisting of n integers, find the contiguous subarray whose length is greater than o ...
- [Swift]LeetCode978. 最长湍流子数组 | Longest Turbulent Subarray
A subarray A[i], A[i+1], ..., A[j] of A is said to be turbulent if and only if: For i <= k < j ...
- [Swift]LeetCode1031. 两个非重叠子数组的最大和 | Maximum Sum of Two Non-Overlapping Subarrays
Given an array A of non-negative integers, return the maximum sum of elements in two non-overlapping ...
- 【IT笔试面试题整理】连续子数组的最大和
[试题描述]输入一个整型数组,数组里有正数也有负数.数组中一个或连续的多个整数组成一个子数组. 求所有子数组的和的最大值.要求时间复杂度O(n). 思路:当我们加上一个正数时,和会增加:当我们加上一个 ...
随机推荐
- MySql5.7及以上 ORDER BY 报错问题
一.问题 本人使用的MySql版本是8.0的 当MySql5.7及以上的版本执行带有 ORDER BY 的SQL语句时可能会报错. 例如,执行以下mysql语句: SELECT id, user_id ...
- Nuxt.js 应用中的 imports:context 事件钩子详解
title: Nuxt.js 应用中的 imports:context 事件钩子详解 date: 2024/10/29 updated: 2024/10/29 author: cmdragon exc ...
- 使用 FastGPT 工作流搭建 GitHub Issues 自动总结机器人
如今任何项目开发节奏都很快,及时掌握项目动态是很重要滴,GitHub Issues 一般都是开发者和用户反馈问题的主要渠道. 然而,随着 Issue 数量的增加,及时跟进每一个问题会变得越来越困难. ...
- 【转载】scipy.stats.norm.ppf —— 分位点函数(CDF的逆)(也被用作“标准偏差乘数”)
原文地址: https://www.cnblogs.com/jiangkejie/p/15292260.html scipy.stats.norm.ppf() 分位点函数(CDF的逆)(也被用作&qu ...
- 在 Github Action 管道内集成 Code Coverage Report
Github Actions 我们的开源项目 Host 在 Github,并且使用它强大的 Actions 功能在做 CICD.单看 Github Actions 可能不知道是啥.其实它就是我们常说的 ...
- 2023NOIP A层联测25 T2 游戏
2023NOIP A层联测25 T2 游戏 优秀且新颖的期望题. 思路 分析问题,由于双方都是最优策略,所以可以说学生知道老师会选择那些教室设置概率(概率设置好就不能改变),老师也知道学生会怎样选择教 ...
- VUE3刷新页面报错:Uncaught SyntaxError: Unexpected token ‘<‘
今天用vue3配置嵌套路由时,发现刷新页面后,页面变为空白,打开控制台发现报错: Uncaught SyntaxError: Unexpected token '<' 解决方法: 修改vue.c ...
- 计算机概念——io 复用
前言 首先什么是io复用呢? 现在web框架没有不用到io复用的,这点是肯定的,不然并发真的很差. 那么io复用,复用的是什么呢?复用的真的不是io管道啥的,也不是io连接啥的,复用的是io线程. 这 ...
- 抓包工具之Fiddler(详解)
Fiddle简介 Fiddler是最强大最好用的Web调试工具之一,它能记录所有客户端和服务器的http和https请求,允许你监视,设置断点,甚至修改输入输出数据,Fiddler包含了一个强大的基于 ...
- S2P主数据助力医药企业建立数据化管理平台
随着国家信息化进程的推进,医药软件行业市场规模正在不断扩大,其应用领域也在逐步拓宽,企业面临着多样化的销售渠道和模式选择.然而,要想在这样的多变市场中占据优势地位,单纯依靠经验决策已经不足以应对挑战. ...