力扣爆刷第169天之TOP200五连刷111-115(课程表、单词搜索、归并)

力扣爆刷第169天之TOP200五连刷111-115(课程表、单词搜索、归并)

一、207. 课程表

题目链接:https://leetcode.cn/problems/course-schedule/description/
思路:本题是一个典型的有向图判定是否有环,如果有环就无法完成课程,因为循环依赖。
1、那么关键点就在于该如何判定有环,我们可以把有向图想象成一个多叉树,如果单条链路上有回路,就相当于有环。
2、另外如果遍历呢?有向图的话一般是采用数组和链表构建邻接表,通过遍历邻接表就可以完成图的遍历。
3、遍历过程中需要注意哪些问题呢?要防止重复遍历,如果防止重复遍历呢?只需要维护一个boolean数组,那个节点遍历过了就给标记一下既可以。
4、如果判定有环呢?因为只要单条链路形成环路即为有环,所以只需要模拟树的遍历,在前序的位置设置标识,在后序的位置移出标识,如果在遍历的过程中,标识被重复遇到了就说明有环路。
拓展:如果存在多条可以修习完课程的路径,如何找出一条,其实只需要在后序遍历的位置,记录节点,最后翻转搜集的节点即可。
基于以上的内容,可以写出下面的代码。

class Solution {
    boolean[] visited;
    boolean[] flag;
    boolean finish = true;
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        visited = new boolean[numCourses];
        flag = new boolean[numCourses];

        List<Integer>[] list = builderGroup(numCourses, prerequisites);
        for(int i = 0; i < numCourses; i++) {
            traverse(i, list);
        }
        return finish;
    }

    void traverse(int from, List<Integer>[] list) {
        if(visited[from]) {
            finish = false;
        }
        if(flag[from] || !finish) {
            return;
        }
        flag[from] = true;
        visited[from] = true;
        for(int to : list[from]) {
            traverse(to, list);
        }
        visited[from] = false;
    }
    

    List<Integer>[] builderGroup(int numCourses, int[][] prerequisites) {
        List<Integer>[] list = new LinkedList[numCourses];
        for(int i = 0; i < numCourses; i++) {
            list[i] = new LinkedList();
        }
        for(int[] temp : prerequisites) {
            list[temp[1]].add(temp[0]);
        }
        return list;
    }
}

二、LCR 125. 图书整理 II

题目链接:https://leetcode.cn/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/description/
思路:本题是用两个栈实现队列,思路不难。
1、实现队列只需要考虑如何先进先出就行,只需要先进栈,再出栈就可以。
2、如何防止乱序,只需要维护A,B两个栈,读取元素都从B中读,B空了就把A中元素都加入到B中,写入元素都写入到A中即可。

class CQueue {
    Deque<Integer> stack1 = new LinkedList<>();
    Deque<Integer> stack2 = new LinkedList<>();
    public CQueue() {

    }
    
    public void appendTail(int value) {
        stack1.push(value);
    }
    
    public int deleteHead() {
        if(!stack2.isEmpty()) return stack2.pop();
        while(!stack1.isEmpty()) {
            stack2.push(stack1.pop());
        }
        if(stack2.isEmpty()) return -1;
        return stack2.pop();
    }
}


/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue obj = new CQueue();
 * obj.appendTail(value);
 * int param_2 = obj.deleteHead();
 */

三、402. 移掉 K 位数字

题目链接:https://leetcode.cn/problems/remove-k-digits/description/
思路:本题是要求从字符串中移除掉k个数字,之后使其表示的数最小。
1、如果让剩余的数足够小?其实数字是有高位和低位的,我们应该从高位往低位进行处理。
2、具体该如何处理呢?我们只需要丢弃掉较大的数,保留较小的数即可。
3、如何丢呢?我们应该丢掉高位较大的数,保留低位较小的数,就可以实现最终的数最小。
4、具体实现可以使用单调栈,如果当前元素小于栈顶元素,则说明,高位元素值大于低位元素值,该丢弃。如果当前元素值大于栈顶元素值,说明低位元素大于高位元素,需要保留下来高位元素,因为高位元素小。

class Solution {
    public String removeKdigits(String num, int k) {
        LinkedList<Character> stack = new LinkedList<>();
        for(int i = 0; i < num.length(); i++) {
            char c = num.charAt(i);
            while(!stack.isEmpty() && c < stack.peek() && k > 0) {
                stack.poll();
                k--;
            }
            stack.push(c);
        }
        while(k > 0 && !stack.isEmpty()) {
            stack.pop();
            k--;
        }
        StringBuilder sb = new StringBuilder();
        while(!stack.isEmpty()) sb.insert(0, stack.pop());
        String res = "";
        for(int i = 0; i < sb.length(); i++) {
            if(sb.charAt(i) != '0') {
                res = sb.toString().substring(i, sb.length());
                break;
            }
        }
        return res.equals("") ? "0" : res;
    }
}

四、79. 单词搜索

题目链接:https://leetcode.cn/problems/word-search/description/
思路:本题求单词搜索,问能不能按照单词自己的顺序,在二维数组中找到它。这其实涉及到了几个点。
1、首先明确,这是一个典型的无向图的遍历题,DFS和BFS都可以,一般我爱用DFS,因为好写不用写栈。
2、其次,要考虑怎么进行单词搜索,可以随着递归维护一个单词读取位置的指针,只要元素相同指针就可以+1,指针只要能够走到结尾部分,就算是搜索结束,搜索到了。
3、如何防止重复遍历,直接使用一个二维boolean数组是比较浪费空间的,可以对遍历过的节点设置为’0’,递归返回时再修改回原本的值,这样就可以完美解决掉重复遍历的问题。
在这里插入图片描述

class Solution {
    boolean flag = false;
    public boolean exist(char[][] board, String word) {
        for(int i = 0; i < board.length; i++) {
            for(int j = 0; j < board[0].length; j++) {
                if(flag) return true;
                dfs(board, word, i, j, 0);
            }
        }
        return flag;
    }
    
    void dfs(char[][] board, String word, int x, int y, int index) {
        if(index == word.length()) {
            flag = true;
            return;
        }
        if(x < 0 || x >= board.length || y < 0 || y >= board[0].length || flag) return;
        if(board[x][y] != word.charAt(index)) return;
        board[x][y] = '0';
        dfs(board, word, x-1, y, index+1);
        dfs(board, word, x, y-1, index+1);
        dfs(board, word, x+1, y, index+1);
        dfs(board, word, x, y+1, index+1);
        board[x][y] = word.charAt(index);
    }
}

五、912. 排序数组

题目链接:https://leetcode.cn/problems/sort-an-array/description/
思路:简单写一个排序算法就可以,不过本题的测试用例专门针对了一下快排,如果用快排的话需要自己处理,我这里用的堆排。
1、从最后一个非叶子节点开始,直到根节点,向下构造最大堆。
2、构造最大堆就是把堆顶的元素找到可以下沉到的具体位置,找到后,就把对应的元素交换位置即可。
3、构造完最大堆以后,堆顶元素就是最大值,只需要不断的把堆顶元素移动到数组尾部即可。

class Solution {
    
    public int[] sortArray(int[] nums) {
        heapSort(nums);
        return nums;
    }

    void heapSort(int[] nums) {
        int len = nums.length;
        for(int i = len/2-1; i >= 0; i--) {
            builderHeap(nums, i, len);
        }
        for(int i = len-1; i > 0; i--) {
            int max = nums[0];
            nums[0] = nums[i];
            nums[i] = max;
            builderHeap(nums, 0, i);
        }

    }
    
    void builderHeap(int[] nums, int start, int end) {
        int k = start, t = nums[start];
        for(int i = start*2+1; i < end; i = i*2+1) {
            if(i+1 < end && nums[i+1] > nums[i]) i = i+1;
            if(t < nums[i]) {
                nums[k] = nums[i];
                k = i;
            }else break;
        }
        nums[k] = t;
    }
}
  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在VS Code上刷力扣LeetCode)题目,首先需要进行以下几步操作: 1. 安装VS Code插件:在VS Code中搜索并安装LeetCode插件。这个插件可以提供LeetCode题目的在线编写和提交功能,以及自动测试和调试代码的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【史上最强代码编辑器VS Code】之VS Code刷力扣LeetCode)题目](https://blog.csdn.net/weixin_44553006/article/details/105183522)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [在 vscode 上刷力扣 Leetcode 可以这样来](https://blog.csdn.net/u012190388/article/details/121277555)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [leetcode答案-algo-study:从零开始刷力扣(LeetCode),JavaScript语言,算法](https://download.csdn.net/download/weixin_38680764/19920528)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

当年拼却醉颜红

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值