1、例题--排列 Permutation 
Given a collection of distinct numbers, return all possible permutations.
For example,
[1,2,3] have the following permutations:
[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1].
public List<List<Integer>> permute(int[] nums) {
// Implement this method.
}

1)边界条件:组合问题,输入为空,输出为空;其他情况都是正常的。

2)思路:第一个位置先选一个数,第二位置从剩下的两个数里面选一个数,第三个位置只能选最后一个数。

那么N个数的Level-N问题这样化简:第一个位置从N个数里面选择一个,剩余N-1位置和N-1个数,生成一个Level-(N-1)的问题,形成递归。

3)代码实现

public List<List<Integer>> permute(int[] nums) {
  List<List<Integer>> numList = new ArrayList<Integer>(); ///错误的new ArrayList<ArrayList<Integer>>()

  Arrays.sort(nums);//排序有什么用?跟大小没有关系.. 有重复数字的情况会有用。

  for (int i = 0 ; i < nums.length; i++) {

    numList.add(nums[i]);  ///将数组转换为Arraylist,方便后面操作

  }

   return permutes(new ArrayList<Integer>(); numList);

}

  /*先实现递归函数主体*/

  public List<List<Integer>> permutes(ArrayList<Integer> cur, ArrayList<Integer> nums) {

    List<List<Integer>> results = new ArrayList<ArrayList<Integer>>();

    if (0 == nums.size()) {

      ///ArrayList<Integer> result = new ArrayList<>(cur);  ///不需要这一行,因为上一层函数已经申请了新的内存空间

      results.add(result);

      return results;

    }

    for (int i = 0; i < nums.size(); i++) {

      List<Integer> newCur = new ArrayList<>(cur);

      newCur.add(nums.get(i));

      List<Integer> newNum = new ArrayList<>(nums);

      newNums.remove(i);

         result.addAll(permutes(newCur, newNum));

    }

    return results;

  }

4)时间复杂度:O(n!);空间复杂度:O(n!)---空间复杂度似乎不准

5)其他解法

a)

public List<List<Integer>> permute(int[] nums) {
  List<List<Integer>> numList = new List<Integer>();

  for (int i = 0 ; i < nums.length; i++) {

    numList.add(nums[i]);

  }

   return permutes(new List<Integer>(); numList);

}

public List<List<Integer>> permutes(List<Integer> cur, List<Integer> num) {

  List<List<Integer>> results = new ArrayList<Integer>();

  if (0 == num.size()) {

    List<Integer> result = new ArrayList<Integer>(cur); //这里申请新内存保持结果,因为上层函数没有申请,只有一个cur在传递。

    results.add(result);///可以简化一下 results.add(new ArrayList<Integer>(cur))

    return results;

  }

  for (int i = 0; i < num.size(); i++) {

    cur.add(num.get(i));

    num.remove(i);

    results.addAll(permutes(cur, num));

    num.add(cur.get(cur,size() - 1));///没有申请新内存,所以要恢复现场

    cur.remove(cur.size() - 1);

  }

  return results;

}

b)

public ArrayList<ArrayList<Integer>> permute(int[] num) {

  ArrayList<ArrayList<Integer>> results = new ArrayList<Integer>();

  Arrays.sort(nums);

  return permutes(new ArrayList<Integer>(), nums);

}

public ArrayList<ArrayList<Integer>> permutes(ArrayList<Integer> cur, int[] nums) {

  ArrayList<ArrayList<Integer>> results = new ArrayList<Integer>();

  if (cur.size() == nums.length) {

    ArrayList<Integer> result = new ArrayList<Integer>(cur);

    results.add(result); ///可以简化一下 results.add(new ArrayList<Integer>(cur))

    return results;

  }

  for (int i = 0; i < nums.length; i++) {

    if (!cur.contains(nums[i])) {

      cur.add(num[i]);

      results.addAll(permutes(cur, nums));

      cur.remove(cur.size() - 1);   

    }

  }

}

c)Use the num array to serve as the "cur"

[0..index-1] means we have already set the first index
numbers
[index..length-1] are the numbers that we haven't set
Example: [4, 3, 5, 8, 1]
choose 8, then swap (4, 8) => [8, 3, 5, 4, 1]
choose 3, do nothing => [8, 3, 5, 4, 1]
choose 1, then swap (5, 1) => [8, 3, 1, 4, 5]
choose 5, then swap (4, 5) => [8, 3, 1, 5, 4]
choose 4, do nothing, => [8, 3, 1, 5, 4]

public ArrayList<ArrayList<Integer>> permute(int[] nums) {

  ArrayList<ArrayList<Integer>> results = new ArrayList<Integer>();

  Arrays.sort(nums);

  permutes(results, nums, 0);

  return results;

}

public void permutes(ArrayList<ArrayList<Integer>> results, int[] nums, int index) {

  if (index == nums.length) {

    ArrayList<Integer> result = new ArrayList<>();
    for (int i = 0; i < nums.length; i++) {

      result.add(nums[i]);

    }

    results.add(result);

    return;

  }

  for (int i = index; i < nums.length; i++) {

    swap(nums, index, i);

    permutes(results, nums, index + 1);

    swap(nums, i, index);    

  }

  return;

}

public void swap(int[] nums, int i, int j)

2、组合--Combination

Given a collection of distinct numbers, return all possible combinations.
For example,
[2, 6, 8] have the following permutations:
[], [2], [6], [8], [2, 6], [2, 8], [6, 8], [2, 6, 8].
public List<List<Integer>> combine(int[] nums) {
// Implement this method.
}

1)边界条件:空集合;输入为空能在正常流程里面处理吗?

2)思路:对于第一个数2有两种情况,选择或者不选择;然后再对[6,8]进行组合。那么对于Level-N的问题,先对第一个数进行选择/不选择,然后对剩余N-1个数进行组合,这样就化为Level-(N-1),形成了递归。

3)代码实现:

public List<List<Integer>> combine(int[] nums) {

  return combines(new ArrayList<Integer>(), nums, 0);

}

public List<List<Integer>> combines(List<Integer> cur, int[] nums, int index) { ---把结果当做出参

  List<List<Integer>> results = new ArrayList<>();

  if (index == nums.length) {

    results.add(new ArrayList<Integer>(cur)); //上一层没有申请内存,这一层申请

    return results;  

  }

  results.addAll(combines(cur, nums, index + 1));

  cur.add(nums[index]);

  results.addAll(combines(cur, nums, index + 1));

  cur.remove(cur.size() - 1); //恢复现场

}

4)时间复杂度:O(2^n);空间复杂度:O(2^n)?

其他解法:把结果当做入参

public List<List<Integer>> combine(int[] nums) {

  List<List<Integer>> results = new ArrayList<>();

  combines(results, new ArrayList<Integer>(), 0);

  return results;

}

public void combines(List<List<Integer>> results, List<Integer> cur, int[] nums, int index) {

  if (index == nums.length) {

    results.add(cur);//直接添加,上一层已经申请了新内存。

    return;

  }

  List<Integer> newCur1 = new ArrayList<>(cur);

  combines(results, newCur1, nums, index + 1);

  List<Integer> newCur2 = new ArrayList<>(cur);//得申请两个新内存,不然也会互相覆盖。申请两个就不用恢复现场了。

  newCur2.add(nums[index]);

  combines(results, newCur2, index + 1);

  return;

}

lecture-7 递归的更多相关文章

  1. [C2P3] Andrew Ng - Machine Learning

    ##Advice for Applying Machine Learning Applying machine learning in practice is not always straightf ...

  2. Cs231n课堂内容记录-Lecture 8 深度学习框架

    Lecture 8  Deep Learning Software 课堂笔记参见:https://blog.csdn.net/u012554092/article/details/78159316 今 ...

  3. 【cs224w】Lecture 1 & 2 - 图的性质 及 随机图

    目录 Lecture 1: Introduction Lecture 2: Properties and Random Graph Degree Distribution Path Length Cl ...

  4. .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]

    方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...

  5. 算法笔记_013:汉诺塔问题(Java递归法和非递归法)

    目录 1 问题描述 2 解决方案  2.1 递归法 2.2 非递归法 1 问题描述 Simulate the movement of the Towers of Hanoi Puzzle; Bonus ...

  6. Android 算法 关于递归和二分法的小算法

     // 1. 实现一个函数,在一个有序整型数组中二分查找出指定的值,找到则返回该值的位置,找不到返回 -1. package demo; public class Mytest { public st ...

  7. 二叉树的递归实现(java)

    这里演示的二叉树为3层. 递归实现,先构造出一个root节点,先判断左子节点是否为空,为空则构造左子节点,否则进入下一步判断右子节点是否为空,为空则构造右子节点. 利用层数控制迭代次数. 依次递归第二 ...

  8. 递归实现n(经典的8皇后问题)皇后的问题

    问题描述:八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后, 使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行.纵行或斜线上 ...

  9. C语言用分别用递归和循环求数字的阶乘的方法

    以下代码均为 自己 实现,嘻嘻! 参考文章:http://blog.csdn.net/talk_8/article/details/46289683 循环法 int CalFactorial(int ...

  10. C#递归解决汉诺塔问题(Hanoi)

    using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace MyExamp ...

随机推荐

  1. windows7下c++11环境搭建

    1.安装codeblocks 13.12 2.下载安装tdm-gcc-4.8.1-3 3.配置coldblocks的编译器(settings->compiler->compiler set ...

  2. 三 akka学习 actor的例子

    (转载: http://blog.csdn.net/chenleixing/article/details/44044243 ) Java并发编程的4种风格:Threads,Executors,For ...

  3. [转]VS 2013 未找到与约束contractname Microsoft.VisualStudio.Utilities.IContentTypeRegistryService...匹配的导出

    前几天,将Visual studio 2013 update 3 升级到了update 5.打开原来的解决方案,出现了 未找到与约束 contractname Microsoft.VisualStud ...

  4. 【总结整理】JQuery基础学习---DOM篇

    前言: 先介绍下需要用到的浏览器提供的一些原生的方法(这里不处理低版本的IE兼容问题) 创建流程比较简单,大体如下: 创建节点(常见的:元素.属性和文本) 添加节点的一些属性 加入到文档中 流程中涉及 ...

  5. Learning Python 004 基础的数据类型和变量

    Python 基础的数据类型和变量 数据类型 整数 Python可以处理任意大小的整数,当然包括负整数. Python表示十六进制也用0x前缀. 浮点数 1.23x10^9和12.3x10^8是完全相 ...

  6. PandaSeq安装报错ltld required, install libtool library

    PandaSeq安装 $ ./autogen.sh && ./configure && make && sudo make install PandaS ...

  7. swiper实现左右滑动图片

    ref:http://www.swiper.com.cn/usage/index.html help:https://segmentfault.com/a/1190000002962202 src: ...

  8. 介绍一款“对话框”组件之 “artDialog”在项目中的使用

    在实际开发项目中经常会用到对话框组件,提示一些信息.其实有很多,例如:在项目中常用到的“Jquery-UI.Jquery-EasyUI”的.Dialog,他们也很强大,Api文档也很多.今天就介绍一款 ...

  9. Spring 属性配置

    此文已由作者尧飘海授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 随着Spring的不断发展与完善,早期它的功能可能只看做是IOC(反转控制)的容器,或者其最大的亮点为DI( ...

  10. 移动端与H5页面像素的差异与关系

    最近工作任务主要是移动端内嵌H5页面,一次与原生进行像素交互下,发现了这个天坑,再次做个记录