【Leetcode】524. Longest Word in Dictionary through Deleting

題目地址:

https://leetcode.com/problems/longest-word-in-dictionary-through-deleting/

給定一個字符串ss,再給定一個字符串組成的數組AA,求所有AA中是ss的子序列的字符串中最長的那個。若答案不唯一,則返回字典序最小的。若答案不存在,則返回空串。

思路是用堆,遍歷數組,然後先判斷當前字符串aa是否是ss的子序列,如果不是直接略過,如果是,則視堆的情況而定:如果堆空,或者字符串aa的長度等於堆頂字符串的長度,則直接入堆;否則的話,如果aa的長度大於堆頂字符串長度,則將堆清空後將aa入堆(因爲我們要返回最長的那個),如果aa的長度小於堆頂字符串長度則直接略過。代碼如下:

import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;

public class Solution {
    public String findLongestWord(String s, List<String> d) {
        PriorityQueue<String> pq = new PriorityQueue<>();
        for (String sub : d) {
            if (isSubsequence(s, sub)) {
                if (!pq.isEmpty() && pq.peek().length() < sub.length()) {
                    pq.clear();
                    pq.offer(sub);
                } else if (pq.isEmpty() || pq.peek().length() == sub.length()) {
                    pq.offer(sub);
                }
            }
        }
        
        // 答案不存在的話要返回空串,所以這裏還需要判斷一下
        return pq.isEmpty() ? "" : pq.peek();
    }
    
    // 判斷sub是否是s的子序列
    private boolean isSubsequence(String s, String sub) {
        int j = 0;
        for (int i = 0; i < s.length() && j < sub.length(); i++) {
            if (s.charAt(i) == sub.charAt(j)) {
                j++;
            }
        }
        
        return j == sub.length();
    }
}

時間複雜度O(l2nlogn)O(l^2n\log n)(判斷子序列需要O(l)O(l),入堆最差需要O(lnlogn)O(ln\log n),雖說看起來時間複雜度很高,但由於堆可能經常清空,所以真實耗時未必有這麼高),空間O(nl)O(nl)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章