【问题标题】:Algorithm LinkedList Problems How to Reduce the Common Intermediate Complex算法 LinkedList 问题 如何减少常见的中间复合体
【发布时间】:2025-12-25 03:25:07
【问题描述】:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.LinkedList;

public class Main {
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        int testcase = Integer.parseInt(br.readLine());

        for(int i = 0; i < testcase; i++) {
            String input = br.readLine();
            LinkedList<Character> list = new LinkedList<>();
            int idx = 0;

            for(int j = 0; j < input.length(); j++) {
                if(input.charAt(j) != '<' && input.charAt(j) != '>' && input.charAt(j) != '-') {
                    list.add(idx, input.charAt(j));
                    idx++;
                    continue;
                }
                if(input.charAt(j) == '<' && idx != 0) {
                    idx--;
                    continue;
                }
                if(input.charAt(j) == '>' && idx <= list.size() - 1) {
                    idx++;
                    continue;
                }
                if(input.charAt(j) == '-' && idx != 0) {
                    list.remove(idx - 1);
                    idx--;
                }
            }

            for(int k = 0; k < list.size(); k++) {
                bw.write(list.get(k));
            }
            bw.write('\n');
        }
        bw.flush();
        bw.close();
    }
}
  • 输入示例

    2
    <<BP<A>>Cd-
    ThIsIsS3Cr3t
    
  • 输出示例

    BAPC
    ThIsIsS3Cr3t
    

时间限制为 2 秒。

我使用 BufferedReader 代替 Scanner 来加速性能,并使用 BufferedWriter 代替 System.out.println()。 但是,正确的答案是超时问题。 有没有办法在使用链表时降低时间复杂度?

【问题讨论】:

  • 你必须使用 LinkedList 吗?我看不出在 ArrayList 上使用它会获得什么。
  • @Ryan 可能是问题的要求。还做了很多从列表中间的插入和删除操作,这是链表比数组更擅长的事情。

标签: java algorithm linked-list time-complexity


【解决方案1】:

LinkedList 上的get() 是一个 O(N) 操作,所以如果你正在寻找速度,应该避免它。您可以改为使用 ListIterator 将光标移入列表,与使用索引相比,它可以更有效地移动,也可以用于插入或删除元素。

您也可以只使用一次input.charAt() 并将结果保存在char 变量中,而不是在同一索引的循环中多次调用它。这是一个快速的函数调用,但为什么调用它的次数超出了您的实际需要,尤其是在时钟下工作时?

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.ListIterator;

public class Main {
    public static void main(String[] args) throws IOException{
        try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
             BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))) {
            int testcase = Integer.parseInt(br.readLine());

            for(int i = 0; i < testcase; i++) {
                String input = br.readLine();
                LinkedList<Character> list = new LinkedList<>();
                ListIterator<Character> cursor = list.listIterator();

                for(int j = 0; j < input.length(); j++) {
                    // I wish Strings were Iterable
                    char c = input.charAt(j);
                    if (c != '<' && c != '>' && c != '-') {
                        cursor.add(c);
                    } else if (c == '<' && cursor.hasPrevious()) {
                        cursor.previous();
                    } else if (c == '>' && cursor.hasNext()) {
                        cursor.next();
                    } else if (c == '-' && cursor.hasPrevious()) {
                        cursor.previous();
                        cursor.remove();
                    }
                }

                for (char c : list) {
                    bw.write(c);
                }
                bw.write('\n');
            }
        }
    }
}

还要注意 try-with-resources 以便读者和作者在完成后自动关闭它们,一个 for-each 循环可以在打印时更有效地迭代整个列表,并使用 if/ else if 在你读到的每个字符的逻辑中。

【讨论】:

  • 字符串可以是可迭代的....有点:for (char c : input.toCharArray()) {