【每日一题】最小区间等

2020/08/04
标注了困难的题目是需要学习方法的,其余的主要是学习java。

文章目录

  • 1.Tues. 课程表
  • 2. Mon. 字符串相加
  • 3. Sun. 二叉树转为链表
  • 4. Sat. 最小区间(hard)
  • 5. 寻宝(困难)

1.Tues. 课程表

一道极其典型的拓扑排序题目,比较推荐的方法就是采用维护一个入度矩阵,采用BFS的方法。这里只写Java方法。

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        List<List<Integer>> edges = new ArrayList<List<Integer>>();
        for (int i = 0; i < numCourses; i++){
            edges.add(new ArrayList<Integer>());
        }
        int[] nums = new int[numCourses];
        for (int[] info: prerequisites){
            edges.get(info[1]).add(info[0]);
            nums[info[0]]++;
        } 
        Queue<Integer> queue = new LinkedList<Integer>();
        for (int i = 0; i<numCourses; i++){
            if (nums[i] == 0) queue.offer(i);
        }

        while (!queue.isEmpty()){
            numCourses--;
            int cur = queue.poll();
            for (int next:edges.get(cur)){
                nums[next]--;
                if (nums[next] == 0) queue.offer(next);
            }
        }
        return numCourses == 0;
    }
}

2. Mon. 字符串相加

主要是学习StringBuffer下的方法。

  • ans.append(string s) 后面加上一个字符串,但是这个也可以是其他类型,会被先转为字符串.
  • ans.reverse() 反转
  • ans.toString() 转为字符串
class Solution {
    public String addStrings(String num1, String num2) {
        int i = num1.length()-1, j = num2.length()-1, add = 0;
        StringBuffer ans = new StringBuffer();
        while(i>=0 || j >= 0 || add!=0){
            int x = i>=0 ? num1.charAt(i)-'0':0;
            int y = j>=0 ? num2.charAt(j)-'0':0;
            int res = x+y+add;
            ans.append(res%10);
            add = res/10;
            i--;
            j--;
        }
        ans.reverse();
        return ans.toString();

    }
}

3. Sun. 二叉树转为链表

主要学习二叉树的方法,判断一个节点有无,是cur == null,声明一个节点是TressNode nex = root.left

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public void flatten(TreeNode root) {
        while (root != null){
            if (root.left != null){
                TreeNode next = root.left;
                while (next.right != null){
                    next = next.right;
                }
                next.right = root.right;
                root.right = root.left;
                root.left = null;
            }
            root = root.right;
        }
        
    }
}

4. Sat. 最小区间(hard)

【每日一题】最小区间等_第1张图片

这道题目还是颇具难度的,思路是采用双指针,但是这里的双指针有一些不一样,可以考虑利用堆。
思路是,构建一个k个数字的堆,每次计算最大值和最小值的差距。

或者采用双指针的方法,维护一个数组统计当前某个数组多少数字被包括。

  • Java方法,主要联系优先队列的使用。需要继承Comparator,重写compare方法。
class Solution {
    public int[] smallestRange(List<List<Integer>> nums) {
        // 注意这里不可以int br = Integer.MAX_VALUE, bl = Integer.MIN_VALUE; 相减会出错
        int br = Integer.MAX_VALUE, bl = 0;
        //int br = 100000, bl = -100000;
        // 这里只能用 size
        int size = nums.size();
        // next 数组配合pq队列,pq队列存储是第几个数组的索引,next是数组的指针,比较的是指针对应的数值的大小。
        int[] next = new int[size];

        // PriorityQueue需要重写Comparator方法
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>(new Comparator<Integer>(){
            // 接口Comparator 需要重写方法compare 需要实现两个数的差
            public int compare(Integer index1, Integer index2){
                return nums.get(index1).get(next[index1])-nums.get(index2).get(next[index2]);
            }
        });
        // PriorityQueue的入队offer,出队poll
        int maxnum = Integer.MIN_VALUE;
        for (int i = 0; i<size; i++ ){
            pq.offer(i);
            maxnum = Math.max(maxnum, nums.get(i).get(0));
        }
        
        while (true){
            int minindex = pq.poll();
            int currange = maxnum - nums.get(minindex).get(next[minindex]);
            if (currange < br-bl){
                br = maxnum;
                bl = nums.get(minindex).get(next[minindex]);
            }
            if (next[minindex] == nums.get(minindex).size()-1) break;
            next[minindex]++;
            maxnum = Math.max(maxnum, nums.get(minindex).get(next[minindex]));
            pq.offer(minindex);

        }
        return new int[]{bl, br};
    }
}

python 方法,参见。

5. 寻宝(困难)

很经典的题目:传送门

你可能感兴趣的:(每日一题)