zoukankan      html  css  js  c++  java
  • LeetCode 392. 判断子序列

    判断子序列

    题目描述

    给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

    你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。

    字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。

    tag

    贪心算法,dp

    题解

    一、 利用双指针进行匹配校验,代码自动校验了当子字符串没有匹配完时而匹配字符串走到尽头的情景,会继续pos++。

      public boolean isSubsequence(String s, String t) {
            int pos = 0;
            for (char c : s.toCharArray()) {
                while (pos < t.length()&&c != t.charAt(pos)) {
                    pos++;
                }
                pos++;
            }
            return pos <= t.length();
        }

    二、记忆化搜索

     public boolean isSubsequence(String s, String t) {
            // 预处理
            t = " " + t; // 开头加一个空字符作为匹配入口
            int n = t.length();
            int[][] dp = new int[n][26]; // 记录每个位置的下一个ch的位置
            for (char ch = 0; ch < 26; ch++) {
                int p = -1;
                for (int i = n - 1; i >= 0; i--) { // 从后往前记录dp
                    dp[i][ch] = p;
                    if (t.charAt(i) == ch + 'a') p = i;
                }
            }
            // 匹配
            int i = 0;
            for (char ch : s.toCharArray()) { // 跳跃遍历
                i = dp[i][ch - 'a'];
                if (i == -1) return false;
            }
            return true;
        }

    三、甚至还有人用了二分法求解

    public boolean isSubsequence(String s, String t) {
            List<Integer>[] idx = new List[256]; // Just for clarity
            for (int i = 0; i < t.length(); i++) {
                if (idx[t.charAt(i)] == null)
                    idx[t.charAt(i)] = new ArrayList<>();
                idx[t.charAt(i)].add(i);
            }
            
            int prev = 0;
            for (int i = 0; i < s.length(); i++) {
                if (idx[s.charAt(i)] == null) return false; // Note: char of S does NOT exist in T causing NPE
                int j = Collections.binarySearch(idx[s.charAt(i)], prev);
                if (j < 0) j = -j - 1;
                if (j == idx[s.charAt(i)].size()) return false;
                prev = idx[s.charAt(i)].get(j) + 1;
            }
            return true;
        }
    呵呵
  • 相关阅读:
    FZU Monthly-201906 tutorial
    FZU Monthly-201906 获奖名单
    FZU Monthly-201905 tutorial
    BZOJ1009 GT考试
    BZOJ2428 均分数据
    模拟退火
    BZOJ3680 吊打XXX
    BZOJ4818 序列计数
    BZOJ4103 异或运算
    BZOJ3512 DZY Loves Math IV
  • 原文地址:https://www.cnblogs.com/jiazhiyuan/p/13288072.html
Copyright © 2011-2022 走看看