算法小知识----11.08----最长公共前缀

88 阅读1分钟

这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

最长定差子序列

该题出自力扣的1218题——最长定差子序列(中等题),题解是自己做的

审题

给你一个整数数组 arr 和一个整数 difference,请你找出并返回 arr 中最长等差子序列的长度,该子序列中相邻元素之间的差等于 difference 。

子序列 是指在不改变其余元素顺序的情况下,通过删除一些元素或不删除任何元素而从 arr 派生出来的序列。

  • 简单概括就是,等差序列,找出数组内最长长度的等差序列,并返回长度

  • 方法的本质就是找到一个数为基准,并且遍历循环,找到与他相关的等差序列并返回最长长度

  • (×)方法一:双重循环

    • 因为,没有等差序列的话,最小的就是本身,所以定义了一个变量存储长度,初值为1

    • for循环外层整个数组,定义每次的局部变量作为每一个遍历的最长长度

    • 内层循环(双指针),if 判断是否等差序列,是的话,直接跳转到相应的序列;最后比较当前等差序列长度,取最大值

          public static int longestSubsequence(int[] arr, int difference) {
              int result = 1;
              for (int i = 0; i < arr.length; i++) {
                  int num = 1;
                  int q = i;
                  for (int j =i+1;j<arr.length;j++){
                      if (arr[j] - arr[q] == difference){
                          num++;
                          q = j;
                          continue;
                      }
                  }
                  result = Math.max(result,num);
              }
              return result;
          }
      
    • 时间复杂度O(n²),空间复杂度O(1),最终被巨型测试用例劝退,超时了

  • (√)方法二:利用HashMap

    • 其实原理就是找到等差序列的初值,利用HashMap对数组的每一个元素都存储当前的值和等差前的值、
    • 假如被等差的值不存在就存储1
    • 最终赋值即可
    • 可以理解成动态规划,对每一次获取到的元素进行存值;时间复杂度O(n),是遍历数组的for循环;空间复杂度是O(n),是定义一个HashMap

编码

    public static int longestSubsequence1(int[] arr, int difference) {
        HashMap<Integer,Integer> map = new HashMap<>(arr.length);
        int res = 0;
        for (int num : arr){
            map.put(num,map.getOrDefault(num - difference,0)+1);
            res = Math.max(res,map.get(num));
        }
        return res;
    }

QQ截图20211106000627.png