Data structures 前缀到后缀转换的时间复杂度?

Data structures 前缀到后缀转换的时间复杂度?,data-structures,stack,time-complexity,postfix-notation,Data Structures,Stack,Time Complexity,Postfix Notation,我认为它应该是二次的,即O(n^2)。我从这个来源阅读。我假设追加两个字符串需要线性时间(O(我们追加的两个字符串的大小之和))并且需要追加的最大次数可以达到O(n),因此总体复杂度为O(n^2)。 有人能判断我是否错了,有人能提供更好的证据吗?是的,你是对的,它是O(n2),我认为你的证据是正确的,但这取决于你必须向谁证明它。可能会显式显示如何构造一个字符串,该字符串将导致O(n)大小的O(n)个追加 下面是一个简单的递归版本,它在O(n)中完成这项工作: 静态字符串预处理(字符串src) {

我认为它应该是二次的,即O(n^2)。我从这个来源阅读。我假设追加两个字符串需要线性时间(O(我们追加的两个字符串的大小之和))并且需要追加的最大次数可以达到O(n),因此总体复杂度为O(n^2)。
有人能判断我是否错了,有人能提供更好的证据吗?

是的,你是对的,它是O(n2),我认为你的证据是正确的,但这取决于你必须向谁证明它。可能会显式显示如何构造一个字符串,该字符串将导致O(n)大小的O(n)个追加

下面是一个简单的递归版本,它在O(n)中完成这项工作:

静态字符串预处理(字符串src)
{
StringBuilder dest=新的StringBuilder(src.length());
对于(int pos=0;pos=src.length())
{
//没有表情
返回pos;
}
charc=src.charAt(pos++);
如果(“+-/*”.indexOf(c)>=0)
{
//运算符。首先转换两个操作数
pos=预结算(目的地、src、pos);
pos=预结算(目的地、src、pos);
}
目的附加(c);
返回pos;
}
迭代版本并不复杂:

static String preToPost2(String src)
{
    StringBuilder dest = new StringBuilder(src.length());
    int pos=0;

    Stack<Character> stk = new Stack<>();
    while(pos < src.length())
    {
        char c = src.charAt(pos++);
        if ("+-/*".indexOf(c)>=0)
        {
            //operator.  After the next 2 expressions, put c
            stk.push(c);
            //after the next expression, just do another one
            stk.push('\0');
            continue;
        }
        dest.append(c);
        // done expression.  check the todo stack
        while(!stk.empty())
        {
            c = stk.pop();
            if (c=='\0')
            {
                break;
            }
            dest.append(c);
            // the append completed another expression, so loop
            // to check the todo stack again
        }
    }
    return dest.toString();
}
静态字符串preToPost2(字符串src)
{
StringBuilder dest=新的StringBuilder(src.length());
int pos=0;
堆栈stk=新堆栈();
而(位置=0)
{
//运算符。在接下来的两个表达式之后,放入c
stk.push(c);
//在下一个表达式之后,再做一个
stk.push('\0');
继续;
}
目的附加(c);
//完成表达式。检查todo堆栈
而(!stk.empty())
{
c=标准流行音乐();
如果(c=='\0')
{
打破
}
目的附加(c);
//追加完成了另一个表达式,因此循环
//再次检查todo堆栈
}
}
返回dest.toString();
}

这是递归的直接转换。

是的,你是对的,它是O(n2),我认为你的证明是正确的,但这取决于你必须向谁证明它。可能会显式显示如何构造一个字符串,该字符串将导致O(n)大小的O(n)个追加

下面是一个简单的递归版本,它在O(n)中完成这项工作:

静态字符串预处理(字符串src)
{
StringBuilder dest=新的StringBuilder(src.length());
对于(int pos=0;pos=src.length())
{
//没有表情
返回pos;
}
charc=src.charAt(pos++);
如果(“+-/*”.indexOf(c)>=0)
{
//运算符。首先转换两个操作数
pos=预结算(目的地、src、pos);
pos=预结算(目的地、src、pos);
}
目的附加(c);
返回pos;
}
迭代版本并不复杂:

static String preToPost2(String src)
{
    StringBuilder dest = new StringBuilder(src.length());
    int pos=0;

    Stack<Character> stk = new Stack<>();
    while(pos < src.length())
    {
        char c = src.charAt(pos++);
        if ("+-/*".indexOf(c)>=0)
        {
            //operator.  After the next 2 expressions, put c
            stk.push(c);
            //after the next expression, just do another one
            stk.push('\0');
            continue;
        }
        dest.append(c);
        // done expression.  check the todo stack
        while(!stk.empty())
        {
            c = stk.pop();
            if (c=='\0')
            {
                break;
            }
            dest.append(c);
            // the append completed another expression, so loop
            // to check the todo stack again
        }
    }
    return dest.toString();
}
静态字符串preToPost2(字符串src)
{
StringBuilder dest=新的StringBuilder(src.length());
int pos=0;
堆栈stk=新堆栈();
而(位置=0)
{
//运算符。在接下来的两个表达式之后,放入c
stk.push(c);
//在下一个表达式之后,再做一个
stk.push('\0');
继续;
}
目的附加(c);
//完成表达式。检查todo堆栈
而(!stk.empty())
{
c=标准流行音乐();
如果(c=='\0')
{
打破
}
目的附加(c);
//追加完成了另一个表达式,因此循环
//再次检查todo堆栈
}
}
返回dest.toString();
}

这是递归的直接转换。

看起来你是对的,但当然你可以用不同的方式实现它,因此它是O(n)。@kaya3你能提供任何这样的教程,在O(n)中做的链接吗?基本上是相同的算法,只需使用二叉树来表示表达式,并将树节点存储在堆栈中而不是字符串中;然后在最后用StringBuilder构建整个输出字符串。看起来你是对的,但当然你可以以不同的方式实现它,因此它是O(n)。@kaya3你能提供任何这样的教程,在O(n)中做的链接吗?基本上是相同的算法,只需使用二叉树来表示表达式,并将树节点存储在堆栈中而不是字符串中;然后在最后使用StringBuilder构建整个输出字符串。