首页 > 其他分享 >leetcode 3266. K 次乘运算后的最终数组 II

leetcode 3266. K 次乘运算后的最终数组 II

时间:2024-12-06 17:43:47浏览次数:4  
标签:index nums int value II length 3266 操作 leetcode

3266. K 次乘运算后的最终数组 II

给你一个整数数组 nums ,一个整数 k  和一个整数 multiplier 。

你需要对 nums 执行 k 次操作,每次操作中:

  • 找到 nums 中的 最小 值 x ,如果存在多个最小值,选择最 前面 的一个。
  • 将 x 替换为 x * multiplier 。

k 次操作以后,你需要将 nums 中每一个数值对 109 + 7 取余。

请你返回执行完 k 次乘运算以及取余运算之后,最终的 nums 数组。

 

示例 1:

输入:nums = [2,1,3,5,6], k = 5, multiplier = 2

输出:[8,4,6,5,6]

解释:

操作结果
1 次操作后 [2, 2, 3, 5, 6]
2 次操作后 [4, 2, 3, 5, 6]
3 次操作后 [4, 4, 3, 5, 6]
4 次操作后 [4, 4, 6, 5, 6]
5 次操作后 [8, 4, 6, 5, 6]
取余操作后 [8, 4, 6, 5, 6]

示例 2:

输入:nums = [100000,2000], k = 2, multiplier = 1000000

输出:[999999307,999999993]

解释:

操作结果
1 次操作后 [100000, 2000000000]
2 次操作后 [100000000000, 2000000000]
取余操作后 [999999307, 999999993]

 

提示:

  • 1 <= nums.length <= 104
  • 1 <= nums[i] <= 109
  • 1 <= k <= 109
  • 1 <= multiplier <= 106

 

解题思路

快速幂
因为和坐标有关系,先定义以下变量
设置了一个node节点来存储元素的值value和对应的坐标index
获取最大值max
数组的长度length
这道题可以分以下思路
1.先把节点排序,在不超过最大值的情况下,和操作次数不超过k的情况下,用优先队列直接操作。复杂度不会超过32 * length。
2.当前的数组中,因为每一个元素 value * m >= max, 所以可以这么说,当操作 length 次的时候,就会是每个数字都会被操作一次.
可以用反证法来证明,若是不是每个数字都会被操作一次,那肯定是最大值没有操作, 但是每个值 value * m >= max 所以,操作 length - 1次的时候,所有的值,都比max大了,那么,max一定能被操作。
3.剩下的次数k中, 就会分为两部分,分别对length取商得到t1,对length取模得到t2
4.对于t2的操作,因为会小于length, 所以可以和步骤一 一样操作。
5.对于t1的操作,根据步骤二的理论,就相当于每个元素都会 * t1, 所以可以用快速幂来解答。

    public int[] getFinalState(int[] nums, int k, int m) {
        if (m == 1) {
            return nums;
        }
        int length = nums.length;
        Node[] nodes = new Node[length];
        int max = 0;
        for (int i = 0; i < length; i++) {
            nodes[i] = new Node(nums[i], i);
            max = Math.max(max, nums[i]);
        }
        int v = getList(nodes, k, m, max);
        if (v == k) {
            for (Node node : nodes) {
                nums[node.index] = (int) (node.value % 1000000007);
            }
            return nums;
        }
        k -= v;
        int t1 = k / length;
        int t2 = k % length;
        getList(nodes, t2, m);

        int mm = mm(m, t1);
//        System.out.println(v + "  " + t1 + "  " + t2 + "  " + mm);
        for (Node node : nodes) {
            nums[node.index] = (int) (node.value * mm % 1000000007);
        }
        return nums;
    }

    public int mm(int m, int t1) {
        long item = m;
        long sum = 1;
        while (t1 != 0) {
            if ((t1 & 1) == 1) {
                sum = sum * item % 1000000007;
            }
            item = item * item % 1000000007;
            t1 >>= 1;
        }
        return (int) sum;
    }

    private int getList(Node[] nodes, int k, int m, int max) {
        int count = 0;
        PriorityQueue<Node> queue = new PriorityQueue<>((a, b) -> a.value == b.value ? Integer.compare(a.index, b.index) : Long.compare(a.value, b.value));
        Collections.addAll(queue, nodes);
        while (queue.peek().value * m <= max) {
            Node poll = queue.poll();
            poll.value = poll.value * m ;
            queue.add(poll);
            count++;
            if (count == k) {
                break;
            }
        }
        return count;
    }

    private void getList(Node[] nodes, int k, int m) {
        int count = 0;
        PriorityQueue<Node> queue = new PriorityQueue<>((a, b) -> a.value == b.value ? Integer.compare(a.index, b.index) : Long.compare(a.value, b.value));
        Collections.addAll(queue, nodes);
        while (count < k) {
            Node poll = queue.poll();
            poll.value = poll.value * m ;
            queue.add(poll);
            count++;
        }
        for (Node node : nodes) {
            node.value = node.value % 1000000007;
        }
    }

    private static class Node {
        private long value;
        private int index;

        public Node(long value, int index) {
            this.value = value;
            this.index = index;
        }
    }

  

 

标签:index,nums,int,value,II,length,3266,操作,leetcode
From: https://www.cnblogs.com/wangzaiguli/p/18591201

相关文章

  • leetcode 3. 无重复字符的最长子串
    3.无重复字符的最长子串给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。 滑动窗口模板//外层循环扩展右边界,内层循环扩展左边界for(intl=0,r=0;r<n;r++){//当前考虑的元素while(l<=r&&check()){//区间[left,right]不符......
  • leetcode第4题 如何求出两个有序数组的中位数
    leetcode原题大意,给定两个升序排列的有序数组,例如nums1=[1,2],nums2=[3,4]那么,这两个有序数组的所有数字的中位数为(2+3)/2=1.5,现在要求以O(log(m+n))的时间复杂度。funcfindMedianSortedArrays(nums1[]int,nums2[]int)float64{ length:=len(nums1)+len(nums2) ......
  • 2024/12/6 【哈希表】LeetCode1.两数之和 【√】
    解法1:暴力解法classSolution:deftwoSum(self,nums:List[int],target:int)->List[int]:foriinrange(len(nums)):des=target-nums[i]ifdesinnums:forjinrange(len(nums)):......
  • LeetCode LCR072[x的平方根]
    题目链接LeetCodeLCR072[x的平方根]详情实例提示题解思路一[暴力法]由于所求的是整型且是正符号整型,可以采取循环遍历的方式来求取平方根用for循环将i由0开始遍历循环体:求i的平方值当平方值小于指定值,此时循环继续退出循环的条件:当平方值为指定值时,返回......
  • leetcode 2056. 棋盘上有效移动组合的数目
    classSolution{private:  vector<vector<int>>RMove={{1,0},{-1,0},{0,1},{0,-1}};  vector<vector<int>>BMove={{1,1},{-1,-1},{-1,1},{1,-1}};public:  boolCheckMove(intsx,intsy,intx,inty,intstep,vector<vector......
  • leetcode2836 在传球游戏中最大化函数值
    n名玩家在玩传球游戏,编号为i的玩家固定会把球传给编号为r[i]的玩家,任选一名玩家开始传球,恰好传k次,得分为这k次传球内所有接触过球的玩家的编号之和,如果玩家多次触球,则累加多次。问从哪个玩家开始传,能获得最大总得分,求最大得分。1<=n<=1E5;0<=r[i]<n;1<=k<=1E10分析:与倍增法求l......
  • LeetCode102 二叉树的层序遍历
    LeetCode102二叉树的层序遍历题目链接:LeetCode102描述给你二叉树的根节点root,返回其节点值的层序遍历。(即逐层地,从左到右访问所有节点)。示例输入:root=[3,9,20,null,null,15,7]输出:[[3],[9,20],[15,7]]思路方法一:迭代方式--借助队列方法二:递归方式代码方法......
  • LeetCode46:全排列
    原题地址:46.全排列-力扣(LeetCode)题目描述给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。示例1:输入:nums=[1,2,3]输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例2:输入:nums=[0,1]输出:[[0,1],......
  • 力扣 LeetCode 51. N皇后(Day14:回溯算法)
    解题思路:每次进入backtracking都表示进入下一行每个backtracking中处理当前行的各个列,看各列是否合法isValid中因为是一行一行向下遍历的,所以对应的当前行一定满足条件,没有放置过其他皇后,只需要看对应的列是否满足即可是否符合需要看左上45°和右上45°,之所以是往上看,......
  • LeetCode LCR126[斐波那契数]
    题目链接LeetCodeLCR126[斐波那契数]详情实例提示题解思路首先想到用递归来求解,F(n)=F(n-1)+F(n-2)但是吧,一看提示啊,0<=n<=100,递归执行100次,那肯定是会超时的噻所以单纯递归肯定是不可行的,此处我采用循环代替递归当n=0时,返回0当n=1时,返回1......