• 每日刷题记录 (三十)


    第一题: 396. 旋转函数

    LeetCode: 396. 旋转函数

    描述:

    给定一个长度为 n 的整数数组 nums 。

    假设 arrk 是数组 nums 顺时针旋转 k 个位置后的数组,我们定义 nums 的 旋转函数 F 为:

    • F(k) = 0 * arrk[0] + 1 * arrk[1] + ... + (n - 1) * arrk[n - 1]

    返回 F(0), F(1), ..., F(n-1) 中的最大值 。

    生成的测试用例让答案符合 32 位 整数。
    在这里插入图片描述

    解题思路:

    1. F(0) = 0*A[0]+1*A[1]+2*A[2]+3*A[3]
      F(1) = 0*A[3]+1*A[0]+2*A[1]+3*A[2]
      F(2) = 0*A[2]+1*A[3]+2*A[0]+3*A[1]
      F(3) = 0*A[1]+1*A[2]+2*A[3]+3*A[0]
    2. F(1)-F(0) = A[0]+A[1]+A[2]-3*A[3]
      F(2)-F(1) = A[0]+A[1]+A[3]-3*A[2]
      F(3)-F(2) = A[0]+A[2]+A[3]-3*A[1]
    3. sum = A[0]+A[1]+A[2]+A[3]
    4. F(3) - F(2) = sum - 4 * A[1]
      F(2) - F(1) = sum - 4 * A[2]
      F(1) - F(0) = sum - 4 * A[3]
    5. F(n) - F(n-1) = sum - len * A(len - n)

    代码实现:

    class Solution {
        public int maxRotateFunction(int[] nums) {
            int sum = 0;
            int max = 0;
            for(int i = 0; i < nums.length; i++) {
                sum += nums[i];// 求 Sum
                max += i * nums[i]; // 求F(0)
            }
            int tmp = max;
            for(int i = 1; i < nums.length; i++) {
                tmp += sum - nums.length * nums[nums.length - i]; // F(n) - F(n-1) =  sum - len * A(len - n)
                max = Math.max(tmp,max);
            }
            return max;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    第二题: 397. 整数替换

    LeetCode: 397. 整数替换

    描述:
    给定一个正整数 n ,你可以做如下操作:

    1. 如果 n 是偶数,则用 n / 2替换 n 。
    2. 如果 n 是奇数,则可以用 n + 1或n - 1替换 n 。

    返回 n 变为 1 所需的 最小替换次数 。
    在这里插入图片描述

    解题思路:

    1. 如果是偶数, 那么就直接 /2
    2. 如果是奇数
      • 首先判断是否为连续的1, 连续1, 就 +1
      • 单个1, 就-1
      • 特殊的3的情况, 直接返回次数+2;

    代码实现:

    class Solution {
        public int integerReplacement(int n) {
            long num = n;
            int res = 0;
            while(num > 1) {
                if(num == 3) return res + 2;
                if(num % 2 == 0){
                    num/=2;
                }else{
                    if((num & 3) == 1) num--;
                    else num++;
                }
                res++;
            }
            return res;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    第三题: 398. 随机数索引

    LeetCode: 398. 随机数索引

    描述:
    给你一个可能含有 重复元素 的整数数组 nums ,请你随机输出给定的目标数字 target 的索引。你可以假设给定的数字一定存在于数组中。

    实现 Solution 类:

    • Solution(int[] nums) 用数组 nums 初始化对象。
    • int pick(int target) 从 nums 中选出一个满足 nums[i] == target 的随机索引 i 。如果存在多个有效的索引,则每个索引的返回概率应当相等。

    在这里插入图片描述

    解题思路:

    1. 这里使用哈希表解题的思路.
    2. key记录当前的数值, value使用List记录所有值为value的下标
    3. pick方法的时候, 获取到存放下标的 List , 然后使用random函数, 随机获取下标, 然后返回.

    代码实现:

    class Solution {
    
        Random random;
        Map<Integer,List<Integer>> map = new HashMap();
        public Solution(int[] nums) {
            random = new Random();
            for(int i = 0; i < nums.length; i++) {
                if(map.containsKey(nums[i])){
                    map.get(nums[i]).add(i);
                }else{
                    List<Integer> list = new ArrayList<>();
                    list.add(i);
                    map.put(nums[i],list);
                }
            }
        }
        
        public int pick(int target) {
            List<Integer> list = map.get(target);
            return list.get(random.nextInt(list.size()));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    第四题: 451. 根据字符出现频率排序

    LeetCode: 451. 根据字符出现频率排序

    描述:
    给定一个字符串 s ,根据字符出现的 频率 对其进行 降序排序 。一个字符出现的 频率 是它出现在字符串中的次数。

    返回 已排序的字符串 。如果有多个答案,返回其中任何一个
    在这里插入图片描述

    解题思路:

    1. 这里首先使用一个数组, 来对字符串中字符出现的次数进行计算.
    2. 在使用一个优先级队列, 堆顶存放次数较多的字符.
    3. 最后进行拼接. 每次弹出堆顶元素.
    4. 拼接好之后进行返回.

    代码实现:

    class Solution {
        public String frequencySort(String s) {
            int[] count = new int[128];
            PriorityQueue<Integer> pq = new PriorityQueue<>((o1,o2)->count[o2] - count[o1]);
            for(char ch : s.toCharArray()) count[ch]++;
            for(int i = 0; i < 128; i++) {
                if(count[i] > 0) {
                    pq.add(i);
                }
            }
            StringBuilder res = new StringBuilder();
            while(!pq.isEmpty()) {
                int top = pq.poll();
                for(int i = 0; i < count[top]; i++) {
                    res.append((char)top);
                }
            }
            return res.toString();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    第五题: 454. 四数相加 II

    LeetCode: 454. 四数相加 II

    描述:
    给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

    • 0 <= i, j, k, l < n
    • nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

    在这里插入图片描述

    解题思路:

    1. 这里使用两两遍历的方式.
    2. 首先对 nums1 , nums2 进行遍历, 每次将遍历到的元素求和, 然后放入哈希表中. key 为对应的和, value为对应和出现的次数
    3. 再去遍历 nums3nums4, 每次将遍历到的和加上负号, 在哈希表中去找, 如果存在, 表示可以和为0, 那么就得到对应的value值, 然后加到结果中.

    代码实现:

    class Solution {
        public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
            Map<Integer,Integer> map = new HashMap<>();
            int ret = 0;
            int res = 0;
            for (int val1 : nums1){
                for (int val2 : nums2) {
                    ret = val1 + val2;
                    if(map.containsKey(ret)) {
                        map.put(ret,map.get(ret) + 1);
                    }else{
                        map.put(ret,1);
                    }
                }
            }
            for (int val1 : nums3){
                for (int val2 : nums4) {
                    ret = val1 + val2;
                    if (map.containsKey(0 - ret)) {
                        res += map.get(0 - ret);
                    }
                }
            }
            return res;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    第六题: 476. 数字的补数

    LeetCode: 476. 数字的补数

    描述:
    对整数的二进制表示取反(0 变 1 ,1 变 0)后,再转换为十进制表示,可以得到这个整数的补数。

    • 例如,整数 5 的二进制表示是 “101” ,取反后得到 “010” ,再转回十进制表示得到补数 2 。

    给你一个整数 num ,输出它的补数。
    在这里插入图片描述

    解题思路:

    1. 这里使用位运算.
    2. 首先去记录这个数字一共占了多少为. 循环去判断这个数是否等于0, 不等于的时候去右移1个.
    3. 每次移动的时候, 再去用一个数字, 在每位都置为1
    4. 例如, 5, 二进制为 101, 占了3个位置. 然后就用另一个数字每位为1, 111, 用这个数字去和 5 进行异或操作.
    5. 异或之后, 就是补数.

    代码实现:

    class Solution {
        public int findComplement(int num) {
            int tmp = num;
            int ret = 0;
            while(tmp > 0) {
                tmp >>= 1;
                ret = (ret << 1) | 1;
            }
            return ret ^ num;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    9/7 dp练习+01背包方案数+求背包具体方案
    C++ STL教程
    企业在数字化转型中可以实现的7个目标
    SpringBoot实践(四十三):整理面试常问的问题
    对C语言函数的再认识
    神经网络前向传播表达式,神经网络的前向传播
    【Unity3D】ASE制作天空盒
    SOA和微服务的介绍
    Flask 部署项目 Nginx + Gunicorn + Flask
    顺序表与链表(下)
  • 原文地址:https://blog.csdn.net/wwzzzzzzzzzzzzz/article/details/125911410