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

卖大米 2020-8-9 801


上岸算法

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

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

No.1整理字符串

★解题思路

在无限循环中判断: 只要还有满足题目条件的字符对, 就删除.

代码展示


class Solution { 
   public String makeGood(String s) { 
       StringBuilder sb = new StringBuilder(s); 
       while (true) { 
           int pos = -1; 
           // 查找满足题目条件的字符对 
           for (int i = 1; i < sb.length(); i++) { 
               char c1 = sb.charAt(i), c2 = sb.charAt(i - 1); 
               if (Character.toLowerCase(c1) == Character.toLowerCase(c2) && c1 != c2) { 
                   pos = i - 1; 
                   break; 
               } 
           } 
           if (pos < 0) { 
               break; 
           } 
           sb.delete(pos, pos + 2); 
       } 
       return sb.toString(); 
   } 
}

从良好的编程习惯来讲, 慎用无限循环. 而在这个场景中我们可以手动设限: 最多循环 s.length() / 2 次.

No.2找出第N个二进制字符串中的K位

解题思路

分析出该题目数据范围不大, 最终字符串长度最长 100 万左右 (2 ^ 20), 所以可以直接模拟生成 S_n.

代码展示


class Solution { 
   public char findKthBit(int n, int k) { 
       StringBuilder sb = new StringBuilder("0"); 
       for (int i = 2; i <= n; i++) { 
           StringBuilder inv = invert(sb); 
           sb.append("1"); 
           sb.append(inv.reverse()); 
       } 
       return sb.charAt(k - 1); 
   } 

   private StringBuilder invert(StringBuilder sb) { 
       StringBuilder res = new StringBuilder(sb); 
       for (int i = 0; i < res.length(); i++) { 
           res.setCharAt(i, (char) (((res.charAt(i) - '0') ^ 1) + '0')); 
       } 
       return res; 
   } 
}

No.3和为目标值的最大数目不重叠非空子数组数目

★解题思路

贪心法. 利用前缀和相减得到区间和. 详见注释.

代码展示


class Solution { 
   public int maxNonOverlapping(int[] nums, int target) { 
       int res = 0; 
       int sum = 0; 
       Set<Integer> set = new HashSet<>(); 
       for (int num : nums) { 
           // sum 表示当前累计的前缀和 
           // set 储存之前的前缀和 
           sum += num; 
           // 若 sum 直接等于 target 或者之前的前缀和中存在 sum - target 
           //  说明找到了一个子数组 (这个子数组以 num 结尾) 
           //  然后 res++, 并清空 set 和 sum 继续寻找下一个子数组 
           // 否则, 将 sum 添加到 set 中, 继续寻找 
           if (set.contains(sum - target) || sum == target) { 
               res++; 
               set.clear(); 
               sum = 0; 
           } else { 
               set.add(sum); 
           } 
       } 
       return res; 
   } 
}

No.4切棍子的最小成本

★解题思路

区间动态规划问题.

设定 f[i][j] 表示 [i, j] 切割点之间的棍子, 切割的最优解.

状态转移 f[i][j] = min{ f[i][k] + f[k][j] + length(i, j) }, 其中 length(i, j) 表示 [i, j] 切割点之间的棍子的长度.

边界 f[i][i] = 0, f[i][i + 1] = 0

注意, 为了使得状态包含整根棍子, 我们需要增加两个切割点, 分别位于 0 和 n.

代码展示


class Solution { 
   public int minCost(int n, int[] cuts) { 
       Arrays.sort(cuts); // 根据样例 2 知, 题目输入未必有序. 所以需要排序. 
       int m = cuts.length; 
       int[][] f = new int[m + 2][m + 2]; 
       for (int len = 2; len <= m+1; len++) { 
           for (int start = 0; start + len <= m+1; start++) { 
               int i = start, j = start + len; 
               f[i][j] = 0x3f3f3f3f; 
               for (int k = i; k <= j; k++) { 
                   f[i][j] = Math.min(f[i][k] + f[k][j] + point(j, n, cuts) - point(i, n, cuts), f[i][j]); 
               } 
           } 
       } 
       return f[0][m+1]; 
   } 

   // 由于我们添加了两个切割点, 所以使用 point 函数获取第 i 个切割点的位置 
   private int point(int i, int n, int[] cuts) { 
       if (i == 0) { 
           return 0; 
       } else if (i > cuts.length) { 
           return n; 
       } 
       return cuts[i - 1]; 
   } 
}

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

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

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

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

最新回复 (0)
返回