上岸 I LeetCode Weekly Contest 199解题报告 刷题解法

卖大米 2020-7-26 697


上岸算法

死磕100%上岸率的精品小班课

关注我们,第一时间获得大厂面试真题讲解

No.1 重新排列字符串

★解题思路

由于 Java 的 String 不可变, 所以需要借助 char[] 或者 StringBuilder 来构建新字符串.

代码展示


class Solution {
   public String restoreString(String s, int[] indices) {
       char[] str = new char[s.length()];
       for (int i = 0; i < s.length(); i++) {
           str[indices[i]] = s.charAt(i);
       }
       return String.copyValueOf(str);
   }
}

No.2 灯泡开关IV

解题思路

从最左边的灯开始, 模拟解决即可 (若灯和需要的状态不同, 则反转)

代码展示


class Solution {
   public int minFlips(String target) {
       int cur = 0;
       int res = 0;
       for (int i = 0; i < target.length(); i++) {
           char c = target.charAt(i);
           if (c != cur + '0') {
               res++; 
               cur ^= 1;
           }
       }
       return res;
   }
}

No.3 好叶子节点对的数量

★解题思路

统计每个节点的子树中, 叶子节点到自己的距离列表.

然后根据左右子树返回的列表统计经过自己的好叶子节点对的数量.

代码展示


class Solution {
   private int res = 0;

   public int countPairs(TreeNode root, int distance) {
       res = 0;
       dfs(root, distance);
       return res;
   }

   private List<Integer> dfs(TreeNode node, int distance) {
       if (node == null) return new ArrayList<>();
       if (node.left == null && node.right == null) {
           List<Integer> a = new ArrayList<>();
           a.add(1);
           return a;
       }
       var left = dfs(node.left, distance);
       var right = dfs(node.right, distance);

       if (node.left == null) return add1(right);
       if (node.right == null) return add1(left);

       // 双指针, 统计有多少对
       int tmp = 0;
       for (int l = 0, r = right.size() - 1; l < left.size(); l++) {
           while (r >= 0 && left.get(l) + right.get(r) > distance) r--;
           if (r >= 0 && left.get(l) + right.get(r) <= distance) {
               tmp += r + 1;
               res += r + 1;
           }
       }

       left.addAll(right);
       Collections.sort(left);
       return add1(left);
   }

   private List<Integer> add1(List<Integer> list) {
       for (int i = 0; i < list.size(); i++) {
           list.set(i, list.get(i) + 1);
       }
       return list;
   }
}

No.4 压缩字符串II

★解题思路

动态规划, 状态和转移方程并不复杂, 代码也很简单, 但是转移的决策可能不太容易想到.

具体见代码注释.

代码展示


class Solution {
   public int getLengthOfOptimalCompression(String s, int k) {
       int n = s.length();
       char[] str = s.toCharArray();
       // dp[i][j] 表示前 i 个字符的子串, 删除 j 个字符时的最优解
       int[][] dp = new int[n + 1][k + 2];
       // 初始化 dp[i][j] = INF, dp[0][0] = 0
       for (int i = 0; i <= n; i++) {
           Arrays.fill(dp[i], 0x3f3f3f3f);
       }
       dp[0][0] = 0;
       for (int i = 1; i <= n; i++) {
           for (int j = 0; j <= k; j++) {
               int cnt = 0, del = 0;
               // 枚举决策, 删除第 i 个到第 t 个之间不同于第 i 个的字符
               for (int t = i; t <= n; t++) {
                   if (str[t - 1] == str[i - 1]) cnt++;
                   else del++;
                   if (j + del <= k) {
                       dp[t][j + del] = Math.min(dp[t][j + del], dp[i - 1][j] + getLen(cnt));
                   }
               }
               // 额外处理删除第 i 个
               dp[i][j + 1] = Math.min(dp[i][j + 1], dp[i - 1][j]);
           }
       }
       return dp[n][k];
   }

   private int getLen(int cnt) {
       return cnt == 0 ? 0 : (cnt == 1 ? 1 : (cnt < 10 ? 2 : 3));
   }
}

杭州上岸算法网络科技有限公司

上岸科技,一家位于西雅图致力于帮助北美小伙伴们上岸的团体。

团队主要由一群怀揣情怀于美国高校毕业的一线IT公司工程师构成。我们坚持采用小班课形式,并结合大量”面试式“和”白板“的教学和交流形式,最终帮助大家提升求职成功概率同时大大减少刷题的痛苦。

正如我们的信仰:我们教的是如何上岸而不仅是算法。

最新回复 (0)
返回