(1)leetcode 392 : 判断子序列 (2) 792 : 匹配子序列单词数

(1)
双指针法

class Solution {
    public boolean isSubsequence(String s, String t) {
        int i = 0 ;
        int j = 0;
        while (i < s.length()  && j < t.length()) {
            if (s.charAt(i) == t.charAt(j)) {
                i ++;
            }
            j ++;
        }
        return i == s.length();
    }
}

二分法

    public boolean isSubsequence(String s, String t) {
      
        List<Integer>[] list = new ArrayList[26];
        for (int i = 0; i < t.length(); i ++) {
            int idx = t.charAt(i) - 'a';
            if (list[idx] == null) 
                list[idx] = new ArrayList<>();
            // 添加索引坐标 进去 时间复杂度 O(n)
            list[idx].add(i);
        }
        //
        int j = 0;
        for (int i = 0 ; i < s.length(); i ++) {
            int idx = s.charAt(i) - 'a';
            // 按顺序 返回匹配位置的最小坐标
            if (list[idx] == null) return false;
            int nearL = nearL(list[idx] , j);
            if (nearL == -1) return false;
            j = list[idx].get(nearL) + 1;
        }
        return true;
    }
        private int nearL(List<Integer> list , int q) {
            int i = 0 ; 
            int j = list.size() - 1;
            int ans = -1;
            while (i <= j) {
                int mid = i + ((j - i) >> 1);
                if (list.get(mid) >= q ) {
                    ans = mid;
                    j = mid - 1;
                }
                else {
                    i = mid + 1;
                }
            }
            System.out.println(ans);
            System.out.println("target "  +  q);
            return ans;
        }

进阶
(2)
二分法

class Solution {
    public int numMatchingSubseq(String s, String[] words) {
        List<Integer>[] idx = new ArrayList[26];
        // 预处理 存储该字符出现的位置
        for (int i = 0 ; i < s.length() ; i ++) {
            int index = s.charAt(i) - 'a';
            if (idx[index] == null) idx[index] = new ArrayList<>();
            idx[index].add(i);
        }
        // 记录答案
         int ans = 0;
        for (String t : words) {
            // t 匹配 s
            int j = 0;
            boolean flag = true;
            for (int i = 0 ; i < t.length() ; i ++) {
                int index = t.charAt(i) - 'a';
                if (idx[index] == null)  {
                        flag = false;
                        break;
                    };
                int pos = nearL(idx[index],j);
                if (pos == -1) {
                    flag = false;
                    break;
                }
                j = idx[index].get(pos) + 1;
            }
            if (flag == true) ans ++;
        }
        return ans;
    }

        private int nearL(List<Integer> list , int target) {
            int l = 0 , r = list.size() - 1,ans = -1;
            while (l <= r) {
                int mid = l + ((r - l) >> 1);
                if (list.get(mid) >= target) {
                        ans = mid;
                        r = mid - 1;
                }else {
                    l = mid + 1;
                }
            }
            return ans;
        }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值