首页 > 其他分享 >2024-12-01:单面值组合的第 K 小金额。用go语言,给定一个整数数组 coins,表示不同面值的硬币,同时给出一个整数 k。你可以使用任意数量的这些硬币,但不能将不同面值的硬币组合在一起。请

2024-12-01:单面值组合的第 K 小金额。用go语言,给定一个整数数组 coins,表示不同面值的硬币,同时给出一个整数 k。你可以使用任意数量的这些硬币,但不能将不同面值的硬币组合在一起。请

时间:2024-12-01 20:29:28浏览次数:12  
标签:硬币 int i32 coins 整数 let 面值 lcm

2024-12-01:单面值组合的第 K 小金额。用go语言,给定一个整数数组 coins,表示不同面值的硬币,同时给出一个整数 k。你可以使用任意数量的这些硬币,但不能将不同面值的硬币组合在一起。请返回可以用这些硬币构成的第 k 个最小金额。

1 <= coins.length <= 15。

1 <= coins[i] <= 25。

1 < = k < = 2 ∗ 1 0 9 1 <= k <= 2 * 10^9 1<=k<=2∗109。

输入:coins = [5,2], k = 7。

输出:12。

解释:给定的硬币可以制造以下金额:

5元硬币产生5的倍数:5, 10, 15, 20等。

2元硬币产生2的倍数:2, 4, 6, 8, 10, 12等。

所有硬币合起来可以产生:2, 4, 5, 6, 8, 10, 12, 14, 15等,12是第7个数。

答案2024-12-01:

chatgpt

题目来自leetcode3116。

大体步骤如下:

1.对给定的硬币面值数组 coins 进行排序,以便后续处理。

2.创建一个空数组 a 用于存放不同面值的硬币。

3.遍历排序后的硬币数组,对于每一个硬币 x:

  • 遍历数组 a 中的每个元素 y,检查是否 x 能整除 y,如果可以,则跳过该硬币 x。

  • 如果 x 不能整除任何已选中的硬币,则将 x 加入数组 a。

4.计算数组 a 的所有子集的最小公倍数,并根据每个子集包含硬币的数量对最小公倍数的正负号进行调整。

5.使用二进制位运算构建所有子集的最小公倍数。

6.使用二进制计数方法判断对应子集的硬币数量是否大于等于 k。

7.输出第 k 个最小金额。

总体而言,这个解决方案涉及对硬币面值进行排序、计算最小公倍数、二进制位运算等操作。时间复杂度取决于硬币面值数组的长度和 k,为 O(2^n * n + n^2 * log(n)),其中 n 为硬币数量。

额外空间复杂度为 O(2^n)。

Go完整代码如下:

package main

import (
	"fmt"
	"slices"
	"sort"
	"math/bits"
)

func findKthSmallest(coins []int, k int) int64 {
	slices.Sort(coins)
	a := coins[:0]
next:
	for _, x := range coins {
		for _, y := range a {
			if x%y == 0 {
				continue next
			}
		}
		a = append(a, x)
	}

	subsetLcm := make([]int, 1<<len(a))
	subsetLcm[0] = 1
	for i, x := range a {
		bit := 1 << i
		for mask, l := range subsetLcm[:bit] {
			subsetLcm[bit|mask] = lcm(l, x)
		}
	}
	for i := range subsetLcm {
		if bits.OnesCount(uint(i))%2 == 0 {
			subsetLcm[i] *= -1
		}
	}

	ans := sort.Search(a[0]*k, func(m int) bool {
		cnt := 0
		for _, l := range subsetLcm[1:] {
			cnt += m / l
		}
		return cnt >= k
	})
	return int64(ans)
}

func gcd(a, b int) int {
	for a != 0 {
		a, b = b%a, a
	}
	return b
}

func lcm(a, b int) int {
	return a / gcd(a, b) * b
}

func main() {
	coins := []int{5,2}
	k := 7
	fmt.Println(findKthSmallest(coins,k))
}

在这里插入图片描述

Rust完整代码如下:

use std::cmp::Ordering;

fn find_kth_smallest(coins: &[i32], k: i32) -> i64 {
    let mut sorted_coins = coins.to_vec();
    sorted_coins.sort_unstable();

    let mut filtered_coins = Vec::new();
    'next: for &x in &sorted_coins {
        for &y in &filtered_coins {
            if x % y == 0 {
                continue 'next;
            }
        }
        filtered_coins.push(x);
    }

    let n = filtered_coins.len();
    let subset_lcm_size = 1 << n;
    let mut subset_lcm = vec![1; subset_lcm_size];

    for (i, &x) in filtered_coins.iter().enumerate() {
        let bit = 1 << i;
        for mask in 0..bit {
            subset_lcm[bit | mask] = lcm(subset_lcm[mask], x);
        }
    }

    for i in 0..subset_lcm_size {
        if i.count_ones() % 2 == 0 {
            subset_lcm[i] *= -1;
        }
    }

    let max_search_value = filtered_coins[0] * k;
    let mut low = 1;
    let mut high = max_search_value;

    while low < high {
        let mid = (low + high) / 2;
        let mut cnt = 0;

        for &l in &subset_lcm[1..] {
            cnt += mid / l;
        }

        if cnt >= k {
            high = mid; // If we have enough counts, we try smaller value
        } else {
            low = mid + 1; // If not enough, we go higher
        }
    }

    low as i64
}

fn gcd(a: i32, b: i32) -> i32 {
    let mut a = a;
    let mut b = b;
    while a != 0 {
        let temp = b;
        b = a;
        a = temp % a;
    }
    b
}

fn lcm(a: i32, b: i32) -> i32 {
    a / gcd(a, b) * b
}

fn main() {
    let coins = vec![5, 2];
    let k = 7;
    println!("{}", find_kth_smallest(&coins, k));
}

在这里插入图片描述

标签:硬币,int,i32,coins,整数,let,面值,lcm
From: https://blog.csdn.net/weixin_48502062/article/details/144173974

相关文章

  • 计算n个a相减(java超大整数)
    输入两个整数a(大于等于1且小于等于9)和n(大于等于1且小于等于80),编程求得并输出下面等式的值:例如:若输入的a为5,n为6,则要计算下面公式的值:555555-55555-5555-555-55-5。【输入形式】从标准输入读入整数a和n,两者之间以一个空格分隔。【输出形式】在标准输出上输出公式的计算结......
  • 超长整数的乘法运算(java版)
    【问题描述】编写程序实现两个超长整数(大于等于0,每个最长80位数字)的乘法运算。【输入形式】从键盘分行读入两个超长整数,要考虑输入高位可能为0的情况(如00083),每行的最后都有回车换行。【输出形式】输出只有一行,是两个长整数的乘法运算结果,从高到低依次输出各位数字,各位数字......
  • 正整数求和(链表)
    问题描述】给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。请你将两个数相加,并以相同形式返回一个表示和的链表。假设除了数字0之外,这两个数都不会以0开头。请根据上下文,将程序补充完整。【输入形式】【输出形......
  • 用选择法对10个整数排序(降序)。
    大学作业,运行不了就把每个for循环里面的int提出来,括号内保留i就行了!!!!!多的我不说了,代码放地下自取自拿,某人在这里求个赞,陆续会更新实验3-5,所有作业都有复制版和详解版,记得关注,谢谢各位:自取版:#include<stdio.h>intmain(){  inta[10];  inti,j,temp,max; ......
  • 使用函数输出一个整数的逆序数
    Description本题要求实现一个求整数的逆序数的简单函数。(注意:逆序后去掉前导0)函数接口定义:intreverse(intnumber);其中函数reverse须返回用户传入的整型number的逆序数。Input一行一个整数n。Output一个整数表示答案。SampleInput1 -12340SampleOutput1-4......
  • 从一个无序的整数数组中,找出最小和最大数之间缺失的数字,要求最小的时间复杂度
    要找到无序整数数组中最小值和最大值之间缺失的数字,并保证最小的时间复杂度,可以使用以下方法:1.使用集合(Set)这是最简洁且时间复杂度较低的方法,时间复杂度为O(n),空间复杂度也是O(n)。functionfindMissingNumbers(arr){if(!arr||arr.length<2){return[];/......
  • 2024-11-30:质数的最大距离。用go语言,给定一个整数数组 nums,请找出两个(可以是相同的)质
    2024-11-30:质数的最大距离。用go语言,给定一个整数数组nums,请找出两个(可以是相同的)质数在该数组中的下标之间的最大距离。提示:nums的长度在[1,3*10^5]之间。nums的每个元素的值在[1,100]。输入保证nums中至少有一个质数。输入:nums=[4,2,9,5,3]。输出:3。解释:nums[1]......
  • 2024-11-28:边界元素是最大值的子数组数目。用go语言,给定一个正整数数组 nums,需要找到
    2024-11-28:边界元素是最大值的子数组数目。用go语言,给定一个正整数数组nums,需要找到满足子数组中第一个和最后一个元素都是该子数组中的最大值的子数组数量。输入:nums=[1,4,3,3,2]。输出:6。解释:总共有6个子数组满足第一个元素和最后一个元素都是子数组中的最大值:......
  • 手写一个使用css3旋转硬币的效果
    <!DOCTYPEhtml><html><head><metacharset="UTF-8"><title>CSS3旋转硬币</title><style>body{background-color:#f0f0f0;display:flex;justify-content:center;align-items:center;min-height:......
  • 05-04-09-拓展 识别整数
    任务描述从键盘输入一串字符(直到字符’.’为止),表示一个非负整数,数字之间被混进了其它字符,请正确输出该整数。如果不包含数字,输出0。输入样例:abc12d3e4x.输出样例:1234输入样例:#0%01X23*4.输出样例:1234#include<stdio.h>#include<stdbool.h>intmain(){......