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

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

时间:2025-01-08 15:32:10浏览次数:3  
标签:posToBit nums int pos bitsMaxPos 按位 数组 go

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 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)

在这里插入图片描述

标签:posToBit,nums,int,pos,bitsMaxPos,按位,数组,go
From: https://blog.csdn.net/weixin_48502062/article/details/145000686

相关文章

  • 基于python+Django+mysql民宿农家乐点评网站系统设计与实现
     博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育、辅导。所有项目都配有从入门到精通的基础知识视频课程,学习后应对毕业设计答辩,提供核心代码讲解,答辩指导。项目配有对应开发......
  • 基于数据可视化+django豆果美食推荐系统
    目录项目介绍系统操作流程 系统架构设计演示视频系统功能实现代码实现 推荐项目项目开发总结为什么选择我 源码获取博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者......
  • 2025-01-08:找到按位或最接近 K 的子数组。用go语言,给定一个数组 nums 和一个整数 k,你
    2025-01-08:找到按位或最接近K的子数组。用go语言,给定一个数组nums和一个整数k,你的目标是找到一个子数组,使得该子数组中所有元素进行按位或运算后的结果与k之间的绝对差值尽量小。具体地,你需要确定一个子数组nums[l..r],使得以下表达式的值最小化:|k-(nums[l]ORnums[l......
  • 代码随想录算法训练营第1天 | 数组理论基础,704. 二分查找,27. 移除元素,977.有序数组的
    1.刷题部分1.1数组基础理论原文链接:代码随想录1.1.1题目内容知识性讲解,点击链接查看原文。1.1.2初见想法是一些很基本的知识,看看有么有什么生疏的。1.1.3看录后想法原来有的语言的二维数组元素地址是可以行与行之间不连续的。1.1.4遇到的困难暂未遇到困难。1.......
  • 数组的常用方法有哪些?
    一、操作方法数组基本操作可以归纳为增、删、改、查,需要留意的是哪些方法会对原数组产生影响,哪些方法不会下面对数组常用的操作方法做一个归纳#增下面前三种是对原数组产生影响的增添方法,第四种则不会对原数组产生影响push()unshift()splice()concat()#push()push()方......
  • 【一文入门】Go语言常用语法和案例
    简介Go语言(Golang)作为一门现代编程语言,以其简洁、并发性强、编译速度快而备受欢迎。它由谷歌开发,旨在解决大型软件项目中的常见问题。对于初学者和有经验的开发者来说,Go语言提供了一套直观的语法和强大的工具集,可以高效地构建可靠的软件解决方案。本篇文章旨在为读者提供......
  • 基于Django+Vue的白酒数据推荐系统
    一、前言......
  • 基于Django+Vue的期货程序化交易系统
    一、前言......
  • golang OpcUaClient
    实现功能packagemainimport("fmt""log""opcuaclient/util/plugin/client/opcclient""os""os/signal""syscall")funcmain(){OPCUATest()//监听操作系统信号,阻塞直到接收到信号......
  • 启航数据结构算法之绮旅,漫步C++智慧之道——LeetCode题海探幽:轮转数组之多元策略演绎
    人无完人,持之以恒,方能见真我!!!共同进步!!文章目录复杂度练习之轮转数组方法1方法2方法3总结复杂度练习之轮转数组题目链接:轮转数组为什么我们把这道题作为复杂度的练习题呢?是因为我们以后做题都会涉及到复杂度的计算,我们要保证我们写的程序不会超出题目的时间......