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

卖大米 2020-6-7 647


No.1 重新排列数组

★解题思路

做好下标的映射即可. 

 对于  i < n , 原数组  i  对应新数组  i 2 , 原数组  i + n  对应新数组  i 2 + 1 .

代码展示


class Solution { 
   public int[] shuffle(int[] nums, int n) { 
       int[] res = new int[nums.length]; 
       for (int i = 0; i < n; i++) { 
           res[i * 2] = nums[i]; 
           res[i * 2 + 1] = nums[i + n]; 
       } 
       return res; 
   } 
}

No.2 数组中的k个最强值

解题思路

首先排序, 找到中位数.

然后从两端开始取最强值 —— 根据强度的定义可知, 与中位数相差越远, 强度越大, 所以排序之后首尾的一定是最强的.

代码展示


class Solution { 
   public int[] getStrongest(int[] arr, int k) { 
       int n = arr.length; 
       Arrays.sort(arr); 
       int m = arr[(n - 1) / 2]; 
       int[] res = new int[k]; 
       int l = 0, r = n - 1; 
       // 从两端开始取 k 个, 哪个更强取哪个 
       for (int i = 0; i < k; i++) { 
           if (stronger(arr[l], arr[r], m)) { 
               res[i] = arr[l++]; 
           } else { 
               res[i] = arr[r--]; 
           } 
       } 
       return res; 
   } 

   // 判断 lhs 是否比 rhs 更强 
   private boolean stronger(int lhs, int rhs, int m) { 
       int absl = Math.abs(lhs - m); 
       int absr = Math.abs(rhs - m); 
       return absl != absr ? absl > absr : lhs > rhs; 
   } 
}

No.3 设计浏览器历史记录

★解题思路

使用一个  ArrayList  和一个下标就可以完成. 具体方案见代码注释.

代码展示


class BrowserHistory { 

   private int index; // 当前页面对应的 history 下标 
   private final List<String> history; // 访问记录 

   public BrowserHistory(String homepage) { 
       index = 0; 
       history = new ArrayList<>(); 
       history.add(homepage); 
   } 

   public void visit(String url) { 
       // 若执行过 back, 那么 index 一定位于 history.size() - 1 之前 
       // 此时可以进行 forward 
       // 按照题意, 执行 visited 之后会抹除可以 forward 的页面 
       // 所以把那些页面 remove 掉 
       while (history.size() - 1 != index) { 
           history.remove(history.size() - 1); 
       } 
       history.add(url); 
       index = history.size() - 1; 
   } 

   public String back(int steps) { 
       // 将 index 向前移动 steps 个位置即可 
       steps = Math.min(steps, index); 
       index -= steps; 
       return history.get(index); 
   } 

   public String forward(int steps) { 
       // 将 index 向后移动 steps 个位置即可 
       steps = Math.min(steps, history.size() - 1 - index); 
       index += steps; 
       return history.get(index); 
   } 
}

No.4

给房子涂色III

★解题思路

动态规划问题:

定义  f[i][j][k] 表示前 i 个房子组成 j 个街区, 最后一个街区颜色为 k 时的最小花费. 每个房子有两种选择: 与前面的房子组成一个街区或者开始一个新的街区.

初始状态设置为 0x3f3f3f3f 表示正无穷 (不设置 Integer.MAX_VALUE 是为了避免涉及加法运算时导致溢出).

注意: 若房子 i 已经被染成颜色 c, 那么只有 f[i][j][c] 有效, 其他的 f[i][j][k] (k != c) 均为无效状态.

代码展示


class Solution { 
   public int minCost(int[] houses, int[][] cost, int m, int n, int target) { 
       int[][][] f = new int[m + 1][target + 1][n]; 
       for (int i = 1; i <= m; i++) { 
           for (int j = 0; j <= target; j++) { 
               Arrays.fill(f[i][j], 0x3f3f3f3f); 
           } 
       } 
       for (int i = 1; i <= m; i++) { 
           if (houses[i - 1] != 0) { // 已经被染色, k 为固定值, 无需枚举 
               int k = houses[i - 1] - 1; 
               // j > i 也是无效状态 (街区数量不能超过房子数量) 
               for (int j = 1; j <= Math.min(target, i); j++) { 
                   f[i][j][k] = f[i - 1][j][k]; // 加入最后一个街区 
                   for (int l = 0; l < n; l++) { // 开始新街区 
                       if (l != k) { 
                           f[i][j][k] = Math.min(f[i - 1][j - 1][l], f[i][j][k]); 
                       } 
                   } 
               } 
           } else { // 尚未被染色 
               for (int j = 1; j <= Math.min(target, i); j++) { 
                   for (int k = 0; k < n; k++) { 
                       f[i][j][k] = f[i - 1][j][k] + cost[i - 1][k]; // 加入最后一个街区 
                       for (int l = 0; l < n; l++) { // 开始新街区 
                           if (l != k) { 
                               f[i][j][k] = Math.min(f[i - 1][j - 1][l] + cost[i - 1][k], f[i][j][k]); 
                           } 
                       } 
                   } 
               } 
           } 
       } 

       int res = 0x3f3f3f3f; 
       for (int i : f[m][target]) { 
           res = Math.min(res, i); 
       } 
       return res < 0x3f3f3f3f ? res : -1; 
   } 
}

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

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

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

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

最新回复 (0)
返回