首页 > 其他分享 >2024-10-30:或值至少 K 的最短子数组 I。用go语言,给定一个非负整数数组 nums 和一个整数 k,我们需要判断数组中是否存在一个最短的非空子数组,使得该子数组所有元素的按位或(OR)运

2024-10-30:或值至少 K 的最短子数组 I。用go语言,给定一个非负整数数组 nums 和一个整数 k,我们需要判断数组中是否存在一个最短的非空子数组,使得该子数组所有元素的按位或(OR)运

时间:2024-10-30 13:43:29浏览次数:6  
标签:nums min int minLen 整数 非负 len 数组

2024-10-30:或值至少 K 的最短子数组 I。用go语言,给定一个非负整数数组 nums 和一个整数 k,我们需要判断数组中是否存在一个最短的非空子数组,使得该子数组所有元素的按位或(OR)运算结果至少为 k。如果找到了这样的子数组,返回其长度;如果不存在,则返回 -1。

输入:nums = [1,2,3], k = 2。

输出:1。

解释:

子数组 [3] 的按位 OR 值为 3 ,所以我们返回 1 。

注意,[2] 也是一个特别子数组。

答案2024-10-30:

chatgpt

题目来自leetcode3095。

大体步骤如下:

代码逻辑分析

1.初始化

  • minLen 被设置为 math.MaxInt32,用于存储找到的最短子数组的长度。

  • n 是数组 nums 的长度。

2.解决方案 1

  • 对于每一个索引 i0n-1,表示当前子数组的结束位置。

  • 对于每一个 ji 递减到 0,表示当前子数组的起始位置。

  • 检查从 ji 这段子数组的按位或结果,调用 isSpecial 函数。

  • 如果返回的结果满足大于等于 k,则更新 minLen 为当前子数组长度 i-j+1 的最小值。

  • 最后,如果没有找到满足条件的子数组,返回 -1;否则返回 minLen

3.isSpecial 函数

  • 接受数组 nums 和子数组的起始、结束索引 ji,以及目标值 k

  • 初始化结果 res0

  • 遍历子数组,计算位或结果 res |= nums[idx]

  • 最后返回一个布尔值,判断 res 是否大于等于 k

4.解决方案 2

  • 该方法做了优化,先检查当前元素 nums[i] 是否已经大于等于 k,如果是,则直接返回 1,因为单独的元素就满足了条件。

  • 同样遍历 j,更新 nums[j]nums[j] | nums[i]。并检查是否满足按位或条件。

  • 如果找到了满足条件的子数组,则更新 minLen

  • 最后根据 minLen 的最终值返回结果。

时间复杂度

  • 解决方案 1:最坏情况下,外层循环和内层循环都是进行 O(n^2) 的遍历。

  • 解决方案 2:外层循环为 O(n),内层循环的最坏情况下为 O(n),因此在某些情况下也可能达到 O(n^2) 的复杂度。

  • 最终时间复杂度:最坏情况为 O(n^2)

空间复杂度

  • 两种解决方案都只使用了常量级的额外空间,主要是用于存储变量 minLen 和中间结果 res,以及输入数组 nums 本身。没有使用额外的数据结构来增加空间开销。

  • 最终空间复杂度O(1)

总结

代码通过两种方式实现了目标,虽然最坏情况下时间复杂度达到 O(n^2) 但在实际操作中,尤其是对于较小的输入数组,可能表现良好。空间复杂度保持在常数级别,确保了算法的高效性。

Go完整代码如下:

package main

import (
	"fmt"
	"math"
)

func minimumSubarrayLength(nums []int, k int) int {
	minLen := math.MaxInt32
	n := len(nums)

	// 解决方案 1 的实现
	for i := 0; i < n; i++ {
		for j := i; j >= 0; j-- {
			if isSpecial(nums, j, i, k) {
				minLen = min(minLen, i-j+1)
			}
		}
	}

	if minLen == math.MaxInt32 {
		return -1
	}
	return minLen
}

func isSpecial(nums []int, j int, i int, k int) bool {
	res := 0
	for idx := j; idx <= i; idx++ {
		res |= nums[idx]
	}
	return res >= k
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

// 解决方案 2 的实现
func minimumSubarrayLengthOptimized(nums []int, k int) int {
	minLen := math.MaxInt32
	n := len(nums)

	for i := 0; i < n; i++ {
		if nums[i] >= k {
			return 1
		}
		for j := i - 1; j >= 0 && (nums[i]|nums[j]) != nums[j]; j-- {
			nums[j] |= nums[i]
			if nums[j] >= k {
				minLen = min(minLen, i-j+1)
			}
		}
	}

	if minLen == math.MaxInt32 {
		return -1
	}
	return minLen
}
func main() {
	nums := []int{1, 2, 3}
	k := 2
	fmt.Println(minimumSubarrayLength(nums, k))
	fmt.Println(minimumSubarrayLengthOptimized(nums, k))
}

在这里插入图片描述

Rust完整代码如下:

use std::cmp;

fn minimum_subarray_length(nums: Vec<i32>, k: i32) -> i32 {
    let mut min_len = i32::MAX;
    let n = nums.len();

    // 解决方案 1 的实现
    for i in 0..n {
        for j in (0..=i).rev() {
            if is_special(&nums, j, i, k) {
                min_len = cmp::min(min_len, (i - j + 1) as i32);
            }
        }
    }

    if min_len == i32::MAX {
        -1
    } else {
        min_len
    }
}

fn is_special(nums: &Vec<i32>, j: usize, i: usize, k: i32) -> bool {
    let mut res = 0;
    for idx in j..=i {
        res |= nums[idx];
    }
    res >= k
}

fn minimum_subarray_length_optimized(nums: Vec<i32>, k: i32) -> i32 {
    let mut min_len = i32::MAX;
    let mut nums = nums.clone(); // 复制一份 nums

    let n = nums.len();

    for i in 0..n {
        if nums[i] >= k {
            return 1;
        }
        for j in (0..i).rev() {
            if (nums[i] | nums[j]) != nums[j] {
                nums[j] |= nums[i];
                if nums[j] >= k {
                    min_len = cmp::min(min_len, (i - j + 1) as i32);
                }
            } else {
                break; // 提高效率,如果不再变化,则可直接跳出
            }
        }
    }

    if min_len == i32::MAX {
        -1
    } else {
        min_len
    }
}

fn main() {
    let nums = vec![1, 2, 3];
    let k = 2;

    println!("{}", minimum_subarray_length(nums.clone(), k));          // 解决方案 1
    println!("{}", minimum_subarray_length_optimized(nums, k));      // 解决方案 2
}

在这里插入图片描述

标签:nums,min,int,minLen,整数,非负,len,数组
From: https://www.cnblogs.com/moonfdd/p/18515696

相关文章

  • 代码随想录算法训练营第六天| leetcode242.有效的字母异位词、leetcode349.两个数组的
    1.leetcode242.有效的字母异位词题目链接:242.有效的字母异位词-力扣(LeetCode)文章链接:代码随想录视频链接:学透哈希表,数组使用有技巧!Leetcode:242.有效的字母异位词哔哩哔哩bilibili自己的思路:首先就是对字符串进行分开成一个一个单独的字母,然后使用列表存储这些数据,再对......
  • C语言顺序表(类似数组结构)
    ////CreatedbyAdministratoron2024/10/25.//顺序表结构//#ifndefORDER_TABLE_H#defineORDER_TABLE_H/*声明顺序表的长度*/#defineSize5/***声明顺序表结构体*/typedefstructTable{int*head;intlength;intsize;}table;/***......
  • 更新 state 中的数组
    同对象一样,当你想要更新存储于state中的数组时,你需要创建一个新的数组(或者创建一份已有数组的拷贝值),并使用新数组设置state。在没有mutation的前提下更新数组每次要更新一个数组时,你需要把一个新的数组传入state的setting方法中。为此,你可以通过使用像filter()和map......
  • javascript 数组 filter
    javascript数组filter在JavaScript中,filter方法被用于创建一个新数组,该数组包含通过提供的函数实现的测试的所有元素。解法1:基本使用方法letnumbers=[4,9,16,25,29];letnewNumbers=numbers.filter(num=>num>10);console.log(newNumbers);//......
  • JS-数组、函数、类与对象
    JS进阶数组数组可以存放任意类型的元素letarr=['小胖',12,true,28.9];console.log(arr,arr.length);增arr[4]='newValue';改arr[4]='changedValue';删不会改变数组的长度,使用undefined赋值deletearr[4];查console.log(arr[4]);//undefined多......
  • 203. 长度最小的子数组
    题目看了卡哥的视频后,写了如下代码:classSolution{public:intminSubArrayLen(inttarget,vector<int>&nums){intresult=INT32_MAX;intsum=0;inti=0,j=0;for(j=0;j<nums.size();j++){......
  • 【OJ题解】C++ 把字符串转换成整数
    ......
  • 977. 有序数组的平方
    题目看了卡哥的讲解视频后,写了如下代码:classSolution{public:vector<int>sortedSquares(vector<int>&nums){vector<int>result;intk=nums.size()-1;inti=0,j=k;while(i<=j){......
  • 复杂度分析,数据结构的数组与链表
    复杂度分析,数据结构的数组与链表参考书籍:Hello算法目录复杂度分析,数据结构的数组与链表复杂度分析时间复杂度空间复杂度数据结构数组与链表数组链表列表复杂度分析复杂度分析是用来判断一个算法效率的手段,执行时所需的时间和空间资源则是正好对应时间和空间复杂度。考虑到执......
  • 560. 和为 K 的子数组(中)
    目录题目法一、暴力枚举法二、前缀和+哈希表优化题目给你一个整数数组nums和一个整数k,请你统计并返回该数组中和为k的子数组的个数。子数组是数组中元素的连续非空序列。示例1:输入:nums=[1,1,1],k=2输出:2示例2:输入:nums=[1,2,3],k=3输出:2法一......