2022-06-14:数组的最大与和。 给你一个长度为 n 的整数数组 nums 和一个整数 numSlots ,满足2 * numSlots >= n 。总共有 numSlots 个篮子,编号为 1

Posted 福大大架构师每日一题

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022-06-14:数组的最大与和。 给你一个长度为 n 的整数数组 nums 和一个整数 numSlots ,满足2 * numSlots >= n 。总共有 numSlots 个篮子,编号为 1相关的知识,希望对你有一定的参考价值。

2022-06-14:数组的最大与和。
给你一个长度为 n 的整数数组 nums 和一个整数 numSlots ,满足2 * numSlots >= n 。总共有 numSlots 个篮子,编号为 1 到 numSlots 。
你需要把所有 n 个整数分到这些篮子中,且每个篮子 至多 有 2 个整数。一种分配方案的 与和 定义为每个数与它所在篮子编号的 按位与运算 结果之和。
比方说,将数字 [1, 3] 放入篮子 1 中,[4, 6] 放入篮子 2 中,这个方案的与和为 (1 AND 1) + (3 AND 1) + (4 AND 2) + (6 AND 2) = 1 + 1 + 0 + 2 = 4 。
请你返回将 nums 中所有数放入 numSlots 个篮子中的最大与和。
力扣2172。

答案2022-06-14:

km算法。

代码用rust编写。代码如下:

fn main() 
    let mut nums: Vec<i32> = vec![1, 2, 3, 4, 5, 6];
    let ans = maximum_and_sum(&mut nums, 3);
    println!("ans = ", ans);


fn maximum_and_sum(arr: &mut Vec<i32>, mut m: i32) -> i32 
    m <<= 1;
    let mut graph: Vec<Vec<i32>> = vec![];
    for i in 0..m 
        graph.push(vec![]);
        for _ in 0..m 
            graph[i as usize].push(0);
        
    
    for i in 0..arr.len() as i32 
        let mut j = 0;
        let mut num = 1;

        while j < m 
            graph[i as usize][j as usize] = arr[i as usize] & num;
            graph[i as usize][(j + 1) as usize] = arr[i as usize] & num;
            num += 1;
            j += 2;
        
    
    return km(&mut graph);


fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T 
    if a > b 
        a
     else 
        b
    


fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T 
    if a < b 
        a
     else 
        b
    


fn km(graph: &mut Vec<Vec<i32>>) -> i32 
    let nn = graph.len() as i32;
    let mut match0: Vec<i32> = vec![];
    let mut lx: Vec<i32> = vec![];
    let mut ly: Vec<i32> = vec![];
    // dfs过程中,碰过的点!
    let mut x: Vec<bool> = vec![];
    let mut y: Vec<bool> = vec![];
    // 降低的预期!
    // 公主上,打一个,降低预期的值,只维持最小!
    let mut slack: Vec<i32> = vec![];
    let mut falsev: Vec<bool> = vec![];
    for _ in 0..nn 
        match0.push(0);
        lx.push(0);
        ly.push(0);
        x.push(false);
        y.push(false);
        slack.push(0);
        falsev.push(false);
    
    let invalid = 2147483647;
    for i in 0..nn 
        match0[i as usize] = -1;
        lx[i as usize] = -invalid;
        for j in 0..nn 
            lx[i as usize] = get_max(lx[i as usize], graph[i as usize][j as usize]);
        
        ly[i as usize] = 0;
    
    for from in 0..nn 
        for i in 0..nn 
            slack[i as usize] = invalid;
        
        x = falsev.clone();
        y = falsev.clone();
        // dfs() : from王子,能不能不降预期,匹配成功!
        // 能:dfs返回true!
        // 不能:dfs返回false!
        while !dfs(
            from,
            &mut x,
            &mut y,
            &mut lx,
            &mut ly,
            &mut match0,
            &mut slack,
            graph,
        ) 
            // 刚才的dfs,失败了!
            // 需要拿到,公主的slack里面,预期下降幅度的最小值!
            let mut d = invalid;
            for i in 0..nn 
                if !y[i as usize] && slack[i as usize] < d 
                    d = slack[i as usize];
                
            
            // 按照最小预期来调整预期
            for i in 0..nn 
                if x[i as usize] 
                    lx[i as usize] = lx[i as usize] - d;
                
                if y[i as usize] 
                    ly[i as usize] = ly[i as usize] + d;
                
            
            x = falsev.clone();
            y = falsev.clone();
            // 然后回到while里,再次尝试
        
    
    let mut ans = 0;
    for i in 0..nn 
        ans += lx[i as usize] + ly[i as usize];
    
    return ans;


// from, 当前的王子
// x,王子碰没碰过
// y, 公主碰没碰过
// lx,所有王子的预期
// ly, 所有公主的预期
// match,所有公主,之前的分配,之前的爷们!
// slack,连过,但没允许的公主,最小下降的幅度
// map,报价,所有王子对公主的报价
// 返回,from号王子,不降预期能不能配成!
fn dfs(
    from: i32,
    x: &mut Vec<bool>,
    y: &mut Vec<bool>,
    lx: &mut Vec<i32>,
    ly: &mut Vec<i32>,
    match0: &mut Vec<i32>,
    slack: &mut Vec<i32>,
    map: &mut Vec<Vec<i32>>,
) -> bool 
    let nn = map.len() as i32;
    x[from as usize] = true;
    for to in 0..nn 
        if !y[to as usize] 
            // 只有没dfs过的公主,才会去尝试
            let d = lx[from as usize] + ly[to as usize] - map[from as usize][to as usize];
            if d != 0 
                // 如果当前的路不符合预期,更新公主的slack值
                slack[to as usize] = get_min(slack[to as usize], d);
             else 
                // 如果当前的路符合预期,尝试直接拿下,或者抢夺让之前的安排倒腾去
                y[to as usize] = true;
                if match0[to as usize] == -1
                    || dfs(match0[to as usize], x, y, lx, ly, match0, slack, map)
                
                    match0[to as usize] = from;
                    return true;
                
            
        
    
    return false;


执行结果如下:


左神java代码

以上是关于2022-06-14:数组的最大与和。 给你一个长度为 n 的整数数组 nums 和一个整数 numSlots ,满足2 * numSlots >= n 。总共有 numSlots 个篮子,编号为 1的主要内容,如果未能解决你的问题,请参考以下文章

《LeetCode之每日一题》:96.数组中最大数对和的最小值

2021-10-18:乘积最大子数组。给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。力扣152。

限长最大连续和

Leetcode练习(Python):数组类:第152题:给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字)。

2022-09-07:给你一个由正整数组成的数组 nums 。 数字序列的 最大公约数 定义为序列中所有整数的共有约数中的最大整数。 例如,序列 [4,6,16] 的最大公约数是 2 。 数组的一个

Postgres将所有数组值与和条件匹配到同一列