[java刷算法]牛客—剑指offer链表复习、手写简易正则匹配

简介: ✨今日三剑JZ17 打印从1到最大的n位数JZ18 删除链表的节点JZ19 正则表达式匹配

文章目录


JZ17 打印从1到最大的n位数


题目描述



思路详解


这里我们考虑到输出的数组,最后的一位数n为几就是几个9。为了方便我们先找出n个10相乘,再减去1,就是我们数组最后一位数了。然后再遍历加入数组就可以。


代码与结果

import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param n int整型 最大位数
     * @return int整型一维数组
     */
    public int[] printNumbers (int n) {
        //找到该n+1位数的最小数字
        int end = 1;
        for(int i = 1; i <= n; i++)
            end *= 10;
        //从1遍历到n+1位数的最小数字输出
        int[] res = new int[end - 1];
        for(int i = 1; i < end; i++)
            res[i - 1] = i;
        return res;
    }
}


JZ18 删除链表的节点


题目描述


思路详解


本题主要考察链表。

思路比较简单,我们只需要遍历找到该节点,之后把该节点的前节点的next,修改为该节点的后节点,那么就跳过了该节点。


代码与结果

import java.util.*;
/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @param val int整型 
     * @return ListNode类
     */
    public ListNode deleteNode (ListNode head, int val) {
        //加入一个头节点
        ListNode res = new ListNode(0);
        res.next = head;
        //前序节点
        ListNode pre = res;
        //当前节点
        ListNode cur = head;
        //遍历链表
        while(cur != null){
            //找到目标节点
            if(cur.val == val){
                //断开连接
                pre.next = cur.next;
                break;
            }
            pre = cur;
            cur = cur.next;
        }
        //返回去掉头节点
        return res.next;
    }
}


JZ19 正则表达式匹配


题目描述


思路详解


本题相当于手写了简易正则。

考虑到多种情况,那么我们考虑使用动态规划进行解题。

设dp[i][j]表示str前i个字符和pattern前j个字符是否匹配。(需要注意这里的i,j是长度,比对应的字符串下标要多1)

(初始条件) 首先,毋庸置疑,两个空串是直接匹配,因此dp[0][0]=true。然后我们假设str字符串为空,那么pattern要怎么才能匹配空串呢?答案是利用’‘字符出现0次的特性。遍历pattern字符串,如果遇到’‘意味着它前面的字符可以出现0次,要想匹配空串也只能出现0,那就相当于考虑再前一个字符是否能匹配,因此dp[0][i]=dp[0][i−2]。

(状态转移) 然后分别遍历str与pattern的每个长度,开始寻找状态转移。首先考虑字符不为’‘的简单情况,只要遍历到的两个字符相等,或是pattern串中为’.‘即可匹配,因此最后一位匹配,即查看二者各自前一位是否能完成匹配,即dp[i][j]=dp[i−1][j−1]。然后考虑’‘出现的情况:

pattern[j - 2] == ‘.’ || pattern[j - 2] == str[i - 1]:即pattern前一位能够多匹配一位,可以用’*'让它多出现一次或是不出现,因此有转移方程dp[i][j]=dp[i−1][j]∣∣dp[i][j−2]

不满足上述条件,只能不匹配,让前一个字符出现0次,dp[i][j]=dp[i][j−2].


代码与结果

import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param str string字符串 
     * @param pattern string字符串 
     * @return bool布尔型
     */
    public boolean match (String str, String pattern) {
        int n1 = str.length();
        int n2 = pattern.length();
        //dp[i][j]表示str前i个字符和pattern前j个字符是否匹配
        boolean[][] dp = new boolean[n1 + 1][n2 + 1];
        //遍历str每个长度
        for(int i = 0; i <= n1; i++){ 
            //遍历pattern每个长度
            for(int j = 0; j <= n2; j++){
                //空正则的情况
                if(j == 0){
                    dp[i][j] = (i == 0 ? true : false);
                //非空的情况下 星号、点号、字符
                }else{
                    if(pattern.charAt(j - 1) != '*'){
                        //当前字符不为*,用.去匹配或者字符直接相同
                        if(i > 0 && (str.charAt(i - 1) == pattern.charAt(j - 1) || pattern.charAt(j - 1) == '.')){
                            dp[i][j] = dp[i - 1][j - 1];
                        }
                    }else{
                        //碰到*
                        if(j >= 2){
                            dp[i][j] |= dp[i][j - 2];
                        }
                        //若是前一位为.或者前一位可以与这个数字匹配
                        if(i >= 1 && j >= 2 && (str.charAt(i - 1) == pattern.charAt(j - 2) || pattern.charAt(j - 2) == '.')){
                            dp[i][j] |= dp[i - 1][j];
                        }
                    }
                }
            }
        }
        return dp[n1][n2];
  }
}




相关文章
|
10月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
10月前
|
人工智能 算法 NoSQL
LRU算法的Java实现
LRU(Least Recently Used)算法用于淘汰最近最少使用的数据,常应用于内存管理策略中。在Redis中,通过`maxmemory-policy`配置实现不同淘汰策略,如`allkeys-lru`和`volatile-lru`等,采用采样方式近似LRU以优化性能。Java中可通过`LinkedHashMap`轻松实现LRUCache,利用其`accessOrder`特性和`removeEldestEntry`方法完成缓存淘汰逻辑,代码简洁高效。
455 0
|
5月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
存储 算法 安全
探究‘公司禁用 U 盘’背后的哈希表算法与 Java 实现
在数字化办公时代,信息安全至关重要。许多公司采取“禁用U盘”策略,利用哈希表算法高效管理外接设备的接入权限。哈希表通过哈希函数将设备标识映射到数组索引,快速判断U盘是否授权。例如,公司预先将允许的U盘标识存入哈希表,新设备接入时迅速验证,未授权则禁止传输并报警。这有效防止恶意软件和数据泄露,保障企业信息安全。 代码示例展示了如何用Java实现简单的哈希表,模拟公司U盘管控场景。哈希表不仅用于设备管理,还在文件索引、用户权限等多方面助力信息安全防线的构建,为企业数字化进程保驾护航。
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
1114 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
算法
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
308 1
|
算法 索引
❤️算法笔记❤️-(每日一刷-141、环形链表)
❤️算法笔记❤️-(每日一刷-141、环形链表)
211 0
|
算法
【❤️算法笔记❤️】-(每日一刷-876、单链表的中点)
【❤️算法笔记❤️】-(每日一刷-876、单链表的中点)
205 0
|
算法
【❤️算法笔记❤️】-每日一刷-23、合并 K 个升序链表
【❤️算法笔记❤️】-每日一刷-23、合并 K 个升序链表
190 0
|
存储 机器学习/深度学习 算法
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
464 30