Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我的Count和Say递归解决方案的空间复杂度是多少?_Java_Algorithm_Recursion_Space Complexity - Fatal编程技术网

Java 我的Count和Say递归解决方案的空间复杂度是多少?

Java 我的Count和Say递归解决方案的空间复杂度是多少?,java,algorithm,recursion,space-complexity,Java,Algorithm,Recursion,Space Complexity,给定一个数字序列:1,11,21,121111221… 在序列中生成数字的规则如下: 1是“1”,所以11。 11是“两个1”,所以是21。 21是“一个2后面跟着一个1”,所以1211。 在这个序列中找到第n个数字。 假设: n从1开始,第一个数字是“1”,第二个数字是“11” 我的解决方案: public String countAndSay(int n) { List<Integer> result = helper(n); StringBuilder sb = new Str

给定一个数字序列:1,11,21,121111221… 在序列中生成数字的规则如下: 1是“1”,所以11。 11是“两个1”,所以是21。 21是“一个2后面跟着一个1”,所以1211。 在这个序列中找到第n个数字。 假设: n从1开始,第一个数字是“1”,第二个数字是“11”

我的解决方案:

public String countAndSay(int n) {
List<Integer> result = helper(n);
StringBuilder sb = new StringBuilder();
for(Integer num : result) {
      sb.append(num);
}
return sb.toString();
}

private List<Integer> helper(int n) {
List<Integer> result = new ArrayList<Integer>();
//base case
if (n == 1) {
     result.add(1);
     return result; 
}
List<Integer> smaller = helper(n - 1);
int count = 1;
for (int i = 0; i < smaller.size(); i++) {
    if (i + 1 > smaller.size() - 1 ||
              !smaller.get(i + 1).equals(smaller.get(i))) {
         result.add(count);
         result.add(smaller.get(i));
         count = 1;
    } else {
         count++;
    }
}
    return result;
}
公共字符串countAndSay(int n){
列表结果=helper(n);
StringBuilder sb=新的StringBuilder();
for(整数num:result){
某人追加(num);
}
使某人返回字符串();
}
私有列表帮助器(int n){
列表结果=新建ArrayList();
//基本情况
如果(n==1){
结果.增加(1);
返回结果;
}
列表较小=帮助者(n-1);
整数计数=1;
对于(int i=0;i<更小的.size();i++){
如果(i+1>更小.size()-1||
!small.get(i+1).等于(small.get(i))){
结果。添加(计数);
结果.add(较小的.get(i));
计数=1;
}否则{
计数++;
}
}
返回结果;
}
我对大O符号空间复杂性的理解是,当方法运行时,最大可能的额外空间不会等待垃圾收集。
因此,我对这个解决方案的空间复杂性的看法是,由于递归调用是由行“List smaller=helper(n-1);”完成的,因此用于较低级别递归调用的额外空间已经在等待垃圾收集。因此,低级别的时间复杂度不应计入当前级别。该解的空间复杂度应为O(n)。我说得对吗?

是的,从java的角度看,你是对的。大O符号表示空间/时间随着输入大小的增加而增长的顺序。代码占用的空间量将随着
n
输入的增加而线性增加。所以这个解决方案的空间复杂度确实是
O(n)

对于递归,空间复杂度涉及最坏情况下递归/函数堆栈中占用的空间。因为当前在递归堆栈中的函数调用不符合当前垃圾收集调用的条件。当调用
helper(1)
时,该程序将占用的最大空间,因为此时
helper(n),helper(n-1)。。。。helper(2)
所有使用本地资源的调用都在递归堆栈中,不符合垃圾收集的条件

但是,您可以在常量空间中执行此操作,而无需递归

public String countAndSay(int n) {
        StringBuilder curr = new StringBuilder("1");
        StringBuilder prev;
        int count;
        char say;
        for (int i = 1; i < n; i++) {
            prev = curr;
            curr = new StringBuilder();       
            count = 1;
            say = prev.charAt(0);

            for (int j = 1, len = prev.length(); j < len; j++) {
                if (prev.charAt(j) != say){
                    curr.append(count).append(say);
                    count = 1;
                    say = prev.charAt(j);
                }
                else count++;
            }
            curr.append(count).append(say);
        }                   
        return curr.toString();

}
此处
x(i)
是执行此块后的结果大小:

int count = 1;
for (int i = 0; i < smaller.size(); i++) {
    if (i + 1 > smaller.size() - 1 ||
              !smaller.get(i + 1).equals(smaller.get(i))) {
         result.add(count);
         result.add(smaller.get(i));
         count = 1;
    } else {
         count++;
    }
}
int count=1;
对于(int i=0;i<更小的.size();i++){
如果(i+1>更小.size()-1||
!small.get(i+1).等于(small.get(i))){
结果。添加(计数);
结果.add(较小的.get(i));
计数=1;
}否则{
计数++;
}
}

您可以使用笔、纸或调试来查看递归罩下的实际情况

是的,从java的角度来看,你是对的。大O符号表示空间/时间随着输入大小的增加而增长的顺序。代码占用的空间量将随着
n
输入的增加而线性增加。所以这个解决方案的空间复杂度确实是
O(n)

对于递归,空间复杂度涉及最坏情况下递归/函数堆栈中占用的空间。因为当前在递归堆栈中的函数调用不符合当前垃圾收集调用的条件。当调用
helper(1)
时,该程序将占用的最大空间,因为此时
helper(n),helper(n-1)。。。。helper(2)
所有使用本地资源的调用都在递归堆栈中,不符合垃圾收集的条件

但是,您可以在常量空间中执行此操作,而无需递归

public String countAndSay(int n) {
        StringBuilder curr = new StringBuilder("1");
        StringBuilder prev;
        int count;
        char say;
        for (int i = 1; i < n; i++) {
            prev = curr;
            curr = new StringBuilder();       
            count = 1;
            say = prev.charAt(0);

            for (int j = 1, len = prev.length(); j < len; j++) {
                if (prev.charAt(j) != say){
                    curr.append(count).append(say);
                    count = 1;
                    say = prev.charAt(j);
                }
                else count++;
            }
            curr.append(count).append(say);
        }                   
        return curr.toString();

}
此处
x(i)
是执行此块后的结果大小:

int count = 1;
for (int i = 0; i < smaller.size(); i++) {
    if (i + 1 > smaller.size() - 1 ||
              !smaller.get(i + 1).equals(smaller.get(i))) {
         result.add(count);
         result.add(smaller.get(i));
         count = 1;
    } else {
         count++;
    }
}
int count=1;
对于(int i=0;i<更小的.size();i++){
如果(i+1>更小.size()-1||
!small.get(i+1).等于(small.get(i))){
结果。添加(计数);
结果.add(较小的.get(i));
计数=1;
}否则{
计数++;
}
}

您可以使用笔、纸或调试来查看递归罩下的实际情况

非常感谢您的回答,并给了我一个更好的解决方案!我对细节还有些困惑。当我们调用help(1)时,所有help(2)到help(n)都在递归堆栈中,但在那个时候,每个堆栈的空间复杂度是O(1),因为我们只创建了一个空列表,最大空间复杂度是(n-1)*O(1)+O(n)(这是helper(1)的列表))=O(n)。我想确定的是这个分析是否正确。另一件让我困惑的事情是,输入大小是恒定的,但空间和时间的复杂性随着输入值的增加而增加。说空间复杂度是O(1)安全吗?再次感谢你的回答!这是一个非常详细的答案。我想我现在明白你的意思了!非常感谢您的回答,并给了我一个更好的解决方案!我对细节还有些困惑。当我们调用help(1)时,所有help(2)到help(n)都在递归堆栈中,但在那个时候,每个堆栈的空间复杂度是O(1),因为我们只创建了一个空列表,最大空间复杂度是(n-1)*O(1)+O(n)(这是helper(1)的列表))=O(n)。我想确定的是这个分析是否正确。另一件让我困惑的事情是,输入大小是恒定的,但空间和时间的复杂性随着输入值的增加而增加。说空间复杂度是O(1)安全吗?再次感谢你的回答!这是一个非常详细的答案。我想我现在明白你的意思了!