AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79295066
Accepted
CodeCrusader
CodeCrusader
Asked: 2024-12-20 00:59:51 +0800 CST2024-12-20 00:59:51 +0800 CST 2024-12-20 00:59:51 +0800 CST

encontre o número de subsequências que são maiores que outra string

  • 772

Dadas duas sequências s de comprimento m e outra sequência t de comprimento n, conte quantas subsequências de s são maiores que t

Uma sequência p é chamada maior que outra sequência q se ela satisfaz os casos abaixo:

a) p[i] > q[i] na primeira posição onde p e q diferem, ou
b) |p| > |q| e q é um prefixo de p (onde |p| denota o comprimento da senha p).

Exemplo:

s = "bab" t = "ab"

Resultado = 5

Explicação:

Valid subsequences of s which are greater than t are
"b"
"ba"
"bb"
"bab"
"b"

restrições: comprimento de s 1 a 10^5 comprimento de t 1 a 100

O comprimento de t pode ser maior que o comprimento de s também com combinações válidas.

Resolvi isso usando uma abordagem recursiva, mas está levando uma complexidade de tempo O(2^n * n).

public class Main {
    private static final int MOD = 1_000_000_007;

    private static void subsequence(String s, int index, String current, List<String> subsequences) {
        if (index == s.length()) {
            if (!current.isEmpty()) {
                subsequences.add(current);
            }
            return;
        }
        subsequence(s, index + 1, current, subsequences);
        subsequence(s, index + 1, current + s.charAt(index), subsequences);
    }

    private static boolean isGreater(String s1, String t) {
        int len1 = s1.length();
        int len2 = t.length();
        for (int i = 0; i < Math.min(len1, len2); i++) {
            if (s1.charAt(i) > t.charAt(i)) {
                return true;
            } else if (s1.charAt(i) < t.charAt(i)) {
                return false;
            }
        }
        return len1 > len2;
    }

    public static int solve(String s, String t) {
        List<String> subsequences = new ArrayList<>();
        subsequence(s, 0, "", subsequences);

        int count = 0;
        for (String e : subsequences) {
            if (isGreater(e, t)) {
                count = (count + 1) % MOD;
            }
        }

        return count;
    }

    public static void main(String[] args) {
        System.out.println(solve("aba", "ab")); // Expected: 3
        System.out.println(solve("bab", "ab")); // Expected: 5
        System.out.println(solve("wrrmkhds", "bebbjvcgzlwtbvasphvm")); // Expected: 255
        System.out.println(solve("o", "h"));   // Expected: 1
    }
}

Como isso pode ser resolvido em menos complexidade de tempo?

java
  • 2 2 respostas
  • 114 Views

2 respostas

  • Voted
  1. Abhijit Sarkar
    2024-12-20T02:49:44+08:002024-12-20T02:49:44+08:00

    Parece que você pode simplesmente criar uma lista auxiliar com os índices das letras que são menores que t[i]. Chame essa lista de x.

    Em seguida, use matemática simples para determinar quantas subsequências você pode formar usando os intervalos entre os índices em x.

    No seu exemplo, x=[1]. Então, temos o primeiro intervalo fechado [0-0]que pode formar 1subsequência. O segundo intervalo é [2-2], que nos dá o intervalo [0-2]. Você pode formar 3C1+3C2+3C3=6subsequências, mas terá que subtrair as subsequências para [0-0](já contado) e [1-1](não incluído). Então, isso nos dá 1+4=5subsequências.

    • 1
  2. Best Answer
    trincot
    2024-12-20T19:50:19+08:002024-12-20T19:50:19+08:00

    Você pode usar uma relação de recorrência e implementá-la com programação dinâmica.

    Se considerarmos um sufixo de 𝑠, começando no índice 𝑖 e um sufixo de 𝑡, começando no índice 𝑗 (vamos usar a notação 𝑠[𝑖:] e 𝑡[𝑗:] para esses sufixos), então temos um problema menor para resolver, ou seja, quantas subsequências do primeiro sufixo são maiores que o segundo sufixo. Podemos usar esse resultado para o problema maior.

    Se quisermos saber a solução para 𝑠[𝑖:] e 𝑡[𝑗:], então temos alguns cenários:

    • Se 𝑠[𝑖:] estiver vazio (ou seja, 𝑖 ≥ 𝑚), então há 0 subsequências.

    • Caso contrário, podemos dividir a contagem de subsequências em dois grupos:

      1. Subsequências que excluem 𝑠[𝑖]

        Esta contagem é igual à solução para 𝑠[𝑖+1:] e 𝑡[𝑗:] (nós apenas removemos 𝑠[𝑖] da entrada)

      2. Subsequências que incluem 𝑠[𝑖]

        • Se 𝑗 ≥ 𝑛 ou 𝑠[𝑖] > 𝑡[𝑗], então os seguintes caracteres de 𝑡 não importam mais, e podemos escolher livremente quais caracteres de 𝑠[𝑖+1:] incluir ou não. Isso representa 2 𝑚-1-𝑖 subsequências possíveis, todas começando com 𝑠[𝑖].

        • Quando 𝑠[𝑖] = 𝑡[𝑗], então a contagem de subsequências é dada pela solução para 𝑠[𝑖+1:] e 𝑡[𝑗+1:]

        • Caso contrário (quando 𝑠[𝑖] < 𝑡[𝑗]), fizemos uma escolha inválida e, portanto, há 0 subsequências para contar neste cenário.

    Mais formalmente, defina 𝑚 como o comprimento de 𝑠, 𝑛 como o comprimento de 𝑡 e 𝑇 𝑖, 𝑗 como o número de subsequências de 𝑠[𝑖:] que são maiores que 𝑡[𝑗:]. Então:

    • 𝑇 𝑖, 𝑗 = 0, quando 𝑖 ≥ 𝑚

    • 𝑇 𝑖, 𝑗 = 𝑇 𝑖+1, 𝑗 + 2 𝑚-1-𝑖 , quando de outra forma 𝑗 ≥ 𝑛 ou 𝑠[𝑖] > 𝑡[𝑗]

    • 𝑇 𝑖, 𝑗 = 𝑇 𝑖+1, 𝑗 + 𝑇 𝑖+1, 𝑗+1 , quando de outra forma 𝑠[𝑖] = 𝑡[𝑗]

    • 𝑇 𝑖, 𝑗 = 0, caso contrário

    No final, precisamos do valor para 𝑇 0, 0

    Para implementar isso, poderíamos usar uma abordagem de baixo para cima, começando com um sufixo vazio de 𝑠 (ou seja, 𝑖 = 𝑚) e, então, aumentar esse sufixo (diminuindo 𝑖). Para cada sufixo, considere 𝑗 diminuindo de 𝑛 para 0. Como 𝑇 𝑖, 𝑗 depende diretamente apenas de 𝑇 𝑖+1, 𝑗 e 𝑇 𝑖+1, 𝑗+1 , na verdade não precisamos armazenar toda essa matriz 𝑇, mas podemos ser suficientes mantendo duas linhas consecutivas dessa matriz apenas na memória.

    Aqui está uma implementação:

        public static int solve(String s, String t) {
            int m = s.length();
            int n = t.length();
            
            int[] dp = new int[n+1];
            int[] dpPrev;
            
            for (int i = m - 1; i >= 0; i--) { // Grow the suffix of s that is considered
                // Take a copy to have a reference to previous results (for smaller s suffix)
                dpPrev = dp.clone(); 
                // There are 2^(length of s[i:]) - 1 non-empty subsequences 
                //     when t[j:] is empty (j == n):
                dp[n] = 2 * dp[n] + 1;
                // Add the cases where s[i] is included in the subsequences
                for (int j = n - 1; j >= 0; j--) {
                    int cmp = Character.compare(s.charAt(i), t.charAt(j));
                           // Add the count of all subsequences of s[s+1:] (+1 for empty one)
                    dp[j] += cmp >  0 ? dpPrev[n] + 1 
                           // Add the count of subsequences of s[i+1:] greater than t[j+1:]
                           : cmp == 0 ? dpPrev[j+1]
                           : 0;
                }
            } 
            return dp[0];
        }
    

    NB: seu código tinha uma constante 1_000_000_007, que não foi mencionada na sua pergunta. Imagino que não será problema para você incorporar o requisito relacionado a essa constante. Preferi mantê-la de fora para focar na pergunta.

    • 1

relate perguntas

  • Lock Condition.notify está lançando java.lang.IllegalMonitorStateException

  • Resposta de microsserviço Muitos para Um não aparece no carteiro

  • Validação personalizada do SpringBoot Bean

  • Os soquetes Java são FIFO?

  • Por que não é possível / desencorajado definir um lado do servidor de tempo limite de solicitação?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve