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

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

时间:2025-01-08 13:21:55浏览次数:7  
标签:posToBit nums int pos 按位 数组 go bit

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,按位,数组,go,bit
From: https://www.cnblogs.com/moonfdd/p/18659525

相关文章

  • 代码随想录算法训练营第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总结复杂度练习之轮转数组题目链接:轮转数组为什么我们把这道题作为复杂度的练习题呢?是因为我们以后做题都会涉及到复杂度的计算,我们要保证我们写的程序不会超出题目的时间......
  • Luogu P2414 NOI2011 阿狸的打字机 题解 [ 紫 ] [ AC 自动机 ] [ 离线思想 ] [ 树状数
    阿狸的打字机:非常牛的AC自动机题。暴力先考虑在暴力的情况下,我们如何计算\(x\)匹配\(y\)的次数。显然,我们会模拟往\(y\)里加字符的过程,在此过程中做KMP进行匹配,统计答案。那么如果涉及多个模式串呢?就可以把KMP加强成AC自动机了。考虑在AC自动机上如何刻画这个......
  • Go 语言与 Tesseract OCR 实现英文数字验证码识别
    Go语言本身不直接支持图像识别,但可以通过调用TesseractOCR引擎来进行图像识别。我们可以使用Go的tesseract包来实现这一功能。一、安装与配置安装TesseractOCR首先,你需要在系统中安装TesseractOCR。安装方法和前面一样:Ubuntu(Linux):bashsudoapt-getupdatesudo......
  • SA(后缀数组)学习笔记
    SA(后缀数组)学习笔记约定下标显示出来太小了,于是可能会用中括号代替下标。定义\(S+T\)为\(S\)与\(T\)这两个字符串的拼接。定义\(S[l:r]=S[l]+S[l+1]+\cdots+S[r]\)。定义\(suf(i)=S[i:n]\),也就是\(S\)的后缀。下文的\(n\)表示\(S\)的串长。将后缀按字典序......