Java每日一练(20230329)

简介: Java每日一练(20230329)

1. 环形链表 II


给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。


为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。


说明:不允许修改给定的链表。

进阶:

   你是否可以使用 O(1) 空间解决此题?

示例 1:

4a18acda10c1606aa5d1132b9de26d61.png


输入:head = [3,2,0,-4], pos = 1

输出:返回索引为 1 的链表节点

解释:链表中有一个环,其尾部连接到第二个节点。



示例 2:

1a6fcfc68d7340c39151075f7fa53150.png

输入:head = [1,2], pos = 0

输出:返回索引为 0 的链表节点

解释:链表中有一个环,其尾部连接到第一个节点。




示例 3:

输入:head = [1], pos = -1

输出:返回 null

解释:链表中没有环。



提示:

  • 链表中节点的数目范围在范围 [0, 10^4]
  • -10^5 <= Node.val <= 10^5
  • pos 的值为 -1 或者链表中的一个有效索引

出处:

https://edu.csdn.net/practice/24061806

代码: 快慢指针

public class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
    }
}
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null || head.next == null) {
            return null;
        }
        ListNode slow = head;
        ListNode fast = head;
        while (true) {
            if (fast == null || fast.next == null) {
                return null;
            }
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow) {
                break;
            }
        }
        slow = head;
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }
        return fast;
    }
}


原理:快慢指针判断链表是否存在环

定义两个指针 slow 和 fast,初始值都为链表头结点 head;slow 指针每次移动一步,fast 指针每次移动两步。如果链表不存在环,fast 指针会先到达链表末尾,此时可以返回 null;如果链表存在环,fast 指针最终会追上 slow 指针,此时可以跳出循环。


计算环的起点

因为快指针的速度是慢指针的两倍,所以当它们相遇时,慢指针在环中走了 k 步,快指针在环中走了 2k 步。假设环的长度为 r,那么 2k = k + nr,即 k = nr;从链表头结点开始,定义一个新的指针 p,它和 slow 指针每次都向前移动一步;当 p 指针到达环的起点时,slow 指针也恰好到达环的起点,此时返回 p 指针即可。




2. 基础语句


原标题: 输出每天是应该学习还是休息还是锻炼

30天中,从第一天开始五天学习,一天休息、一天锻炼,输出每天是应该学习还是休息还是锻炼

出处:

https://edu.csdn.net/practice/24061807

代码:

public class HelloWorld {
    public static void main(String []args) {
        int n1=0,n2=0,n3=0,i;
        for(i=1;i<=30;i++){
            if(n1<5){
                System.out.println("学习");
                n1++;
                continue;
            }
            else{
                System.out.println("休息");
                System.out.println("锻炼");
                n1=0;
                i++;
            }
        }
    }
}


3. 最小覆盖子串


给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。

注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。


示例 1:

输入:s = "ADOBECODEBANC", t = "ABC"

输出:"BANC"


示例 2:

输入:s = "a", t = "a"

输出:"a"


提示:

   1 <= s.length, t.length <= 105

   s 和 t 由英文字母组成

进阶:你能设计一个在 o(n) 时间内解决此问题的算法吗?

出处:

https://edu.csdn.net/practice/24061808

代码:


public class Min_Win_Sub {
    public String minWindow(String s, String t) {
        int[] ta = new int[128];
        int[] sa = new int[128];
        int min = Integer.MAX_VALUE;
        String minwin = "";
        for (int i = 0; i < t.length(); i++) {
            ta[t.charAt(i)]++;
        }
        int count = 0;
        int end = 0;
        int start = 0;
        while (end < s.length()) {
            if (ta[s.charAt(end)] != 0) {
                if (sa[s.charAt(end)] < ta[s.charAt(end)]) {
                    count++;
                }
                sa[s.charAt(end)]++;
            }
            if (count == t.length()) {
        while (ta[s.charAt(start)] == 0 || sa[s.charAt(start)] > ta[s.charAt(start)]) {
            if (sa[s.charAt(start)] > ta[s.charAt(start)]) {
                sa[s.charAt(start)]--;
            }
            start++;
        }
                if (end - start + 1 < min) {
                    minwin = s.substring(start, end + 1);
                    min = end - start + 1;
                }
            }
            end++;
        }
        return minwin;
    }
}

在滑动窗口中,start 指向窗口左边界,end 指向窗口右边界。当窗口中的字符数目达到了 t 中字符的数目,就需要尝试缩小窗口大小。这时候可以让 start 指针不断右移,直到当前窗口不再满足条件。


具体地,如果当前窗口中的字符 c 不在字符串 t 中,或者 c 在窗口中的数目大于等于 c 在 t 中的数目,那么就可以让 start 右移,并更新窗口中字符 c 的数目。直到当前窗口中的字符数目不再满足要求,停止右移。


要注意,在右移 start 指针的过程中,不仅需要更新窗口中字符 c 的数目,还需要判断当前字符是否在 t 中,避免将不在 t 中的字符加入到窗口中。




目录
相关文章
|
安全 Java C++
2023-3-25 java选择题每日一练
2023-3-25 java选择题每日一练
128 1
CSDN每日一练(Java)--小艺的英文名
CSDN每日一练(Java)--小艺的英文名
|
C++ Python Rust
Rust 重载运算符|复数结构的“加减乘除”四则运算
Rust 重载运算符|复数结构的“加减乘除”四则运算
264 0
Rust 重载运算符|复数结构的“加减乘除”四则运算
|
Linux
Linux 终端命令之文件浏览(1) cat
Linux 终端命令之文件浏览(1) cat
157 0
Linux 终端命令之文件浏览(1) cat
|
Go Python Rust
Rust 编程小技巧摘选(7)
Rust 编程小技巧摘选(7)
348 0
Rust 编程小技巧摘选(7)
|
Rust 索引
Rust 编程小技巧摘选(6)
Rust 编程小技巧摘选(6)
216 1
Rust 编程小技巧摘选(6)
|
Linux Windows Ubuntu
Windows 使用 Linux 子系统,轻轻松松安装多个linux
Windows 使用 Linux 子系统,轻轻松松安装多个linux
1652 0
Windows 使用 Linux 子系统,轻轻松松安装多个linux
|
C++ Rust NoSQL
Rust 数据类型 之 类C枚举 c-like enum
Rust 数据类型 之 类C枚举 c-like enum
194 0
Rust 数据类型 之 类C枚举 c-like enum
|
Java Go C++
Golang每日一练(leetDay0120) 反转字符串中的元音字母、前K个高频元素
Golang每日一练(leetDay0120) 反转字符串中的元音字母、前K个高频元素
205 0
Golang每日一练(leetDay0120) 反转字符串中的元音字母、前K个高频元素
|
Java Go C++
Golang每日一练(leetDay0116) 路径交叉、回文对
Golang每日一练(leetDay0116) 路径交叉、回文对
161 0
Golang每日一练(leetDay0116) 路径交叉、回文对