迭代
迭代:迭代简单来讲就是循环:类比于我们循环输出某一个字符数组时的情景:从字符数组中不断取出字符,再将字符输出。迭代的循环过程则是从栈(或者队列)中不断取出要操作的元素,进行操作,与普通循环过程不同的是在不断取出元素的同时也会向栈中放入元素,从而实现迭代过程。因而迭代的要点有:迭代的初始条件,迭代过程中迭代元素生成,迭代结束条件判断。
迭代示例:
斐波那契数列
//迭代,时间复杂度O(n),空间复杂度O(1)
int fib2(int n)
{
if (n < 2)
return n;
int n0 = 0, n1 = 1;
int temp;
for (int i = 2; i <= n; i++)
{
temp = n0;
n0 = n1;
n1 = temp + n1;
}
return n1;
}
递归
递归:递归简单来讲就是函数的自身调用:要实现这个过程,函数要包含循环的条件和调用自身的语句,通过这个不断自身调用的过程把问题不断化简,最终达到解决的目的。
递归类型:(主要分为递归产生返回值和递归处理引用入参这两种情形)
1.递归产生返回值
//示例1:斐波那契数列: 普通递归,时间复杂度O(2^n),空间复杂度O(n)
int fib(int n)
{
if (n < 2)
return n;
return fib0(n - 1) + fib0(n - 2);
}
//示例2:验证数独九宫格的有效性
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
bool row [9][9]={false}; //row的index和num
bool col [9][9]={false}; //col的index和num
bool block [9][9]={false}; //block的index和num
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j] != '.') {
int num = board[i][j] - '1';//数独中的1~9 在数组中作为0~8
int blockindex = (i/ 3) * 3 + j / 3;
if (row[i][num] || col[j][num] || block[blockindex][num])
return false;
row[i][num] = true;
col[j][num] = true;
block[blockindex][num] = true;
}
}
}
return true;
}
};
2.递归处理入参(入参为引用的形式)
示例:给定一个没有重复数字的序列,返回其所有可能的全排列
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
if (nums.size() == 0)
return vector<vector<int>>{};
vector<vector<int>> res;
func(nums,0,res);
return res;
}
void func(vector<int> nums, int index, vector<vector<int>>& res){
if (index == nums.size()-1)
{
res.push_back(nums);
return;
}
for (int i = index; i < nums.size(); i++){
int temp = nums[index];
nums[index] = nums[i];
nums[i] = temp;
func(nums, index + 1, res);
temp = nums[index];
nums[index] = nums[i];
nums[i] = temp;
}
}
};
循环与遍历
循环: 循环和迭代的共同点在于,它们都是在描述一个多次操作。不同点在于,【循环】侧重于描述每次操作和上一次操作相同之处,而【迭代】侧重于描述每次操作和上一次操作的不同之处。
遍历: 遍历:依次对集合中的每个元素做且仅做一次访问。依次,代表具有某种顺序。比如二叉树有三种前序、中序、后序遍历。数组有顺序、逆序遍历等等。
区别
区别: 迭代大多是循环for\while的形式解决问题,函数内部主要是循环逻辑的处理。递归则是函数调用函数本身。迭代:循环结构,例如for,while循环。递归:选择结构,例如if else 调用自己,并在合适时机退出。迭代与普通循环的区别是:迭代时,循环代码中参与运算的变量同时是保存结果的变量,当前保存的结果作为下一次循环计算的初始值。递归与普通循环的区别是:循环是有去无回(比如循环打印),而递归则是有去有回(因为存在终止条件)。在循环的次数较大的时候,迭代的效率明显高于递归。