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:

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)

在这里插入图片描述

posted @   福大大架构师每日一题  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
历史上的今天:
2024-01-08 文心一言 VS 讯飞星火 VS chatgpt (174)-- 算法导论13.3 3题
2023-01-08 2023-01-08:小红定义一个仅有r、e、d三种字符的字符串中, 如果仅有一个长度不小于2的回文子串,那么这个字符串定义为“好串“。 给定一个正整数n,输出长度为n的好串有多少个。 结果对10^9
2022-01-08 2022-01-08:数组中只有0和1,每过1代,0旁边只有1个1,当前0会变成1。每过1代,0旁边有2个1,当前0还是0。 比如10001,经过1代,会变成11011,再过1代,还是11011 。
2021-01-08 2021-01-08:cpu和gpu有什么区别?
点击右上角即可分享
微信分享提示