选择题
Promise.all, race,allSettled
下面关于Promise说法正确的是(注意“返回结果”的意思包含成功或者失败):
A. Promise.all在所有给定的promise都fulfilled后才返回结果
B. Promise.race在给定的promise中,某个fulfilled后才返回结果
C. promise.then的回调函数中,可以返回一个新的promise
D. 对于一个向后台获取数据已经产生结果的promise:p1,再次调用p1.then,不会去重新发起请求获取数据
答案:CD
Promise.all
是指,将多个promise包装成数组,一起触发,若全部fulfilled则成功,若有一个rejected则失败,整体抛出的异常为第一个失败的promise抛出的异常。最终只返回一个Promise,若全部成功,则返回的value为一个数组,包装时内部的顺序与完成后的顺序一致。
Promise.race
是指,将多个promise包装成数组,一起触发,只要有一个且是第一个成功或失败则整体的结果就是这个promise的结果。该方法只返回一个Promise
Promise.allSettled
是指,将多个promise包装成数组,一起触发,当全部子内容完成后返回一个Promise,其中有results表示结果。
Vue、React 双向数据流
注意双向数据流和双向绑定的区别,vue和react都是双向数据流,只不过一个是单向绑定,一个是双向绑定。
HTTPS
会改变原数组的数组方法 push splice
concat slice 等会返回一个新数组
map 会使用返回值的方法返回一个新数组
outline-width 不会触发回流
因为outline-width轮廓线不会占据空间
附加题:动态规划
前言
其实这个题是比较难直接想到一维动态规划的,因为,牵扯到要证明满足一个前缀和原理的问题。
就是为什么i到j的步数,等于1到 j
的步数 减去1到 i
的步数,即 step{i, j} = step{1, j} - step{1, i}
很多人在这里直接直接用了这个规则,但是我在做题的时候是没有想通这一点的,因此我在看到别人的题解之后还是比较震惊的,居然满足前缀和公式。
因为我的理解是,当你从1到 i
或从1到 j
时,必定满足,前面已走过的节点必定是偶数倍,但是从 i
到 j
则不然,i
之前的节点不一定是要偶数的,这两个问题的状态是不一样的。
我的思路
接下来说说我的思路,我使用的是记忆化搜索。我觉得这个是比较容易直接想到的方法。一维想不出来就用二维,dp[i][j]
表示,从i到j所需的步数。我们最终求解的目的是 dp[1][n+1]
。
我们设在一个计算单元内的思路是这样的:
目标 x -> y 必定会经过下面的步骤
x -> y-1 这是第一次达到 y-1,消耗a1步
y-1 -> c[y-1] 经过规则1返回上一个规定的位置,消耗1步
c[y-1] -> y-1 第二次达到y-1,消耗a2步
y-1 -> y 最终达到y,消耗1步
总消耗a1+a2+2步
因此这个计算单元其实很好写
int getStep(int start, int end) {
if (dp[start][end] != -1) return dp[start][end];
int a1 = getStep(start, end - 1);
a1 += 1;
int a2= getStep(c[end-1], end-1);
a2 += 1;
return (a1 + a2) % M;
}
但是学过动态规划就知道,这样会造成大量的重复计算,因此需要改造:
int getStep(int start, int end) {
if (dp[start][end] != -1) return dp[start][end];
int a1 = getStep(start, end - 1);
int a2= getStep(c[end-1], end-1);
dp[start][end] = a1 + a2 + 2;
return dp[start][end]%M;
}
对于一次 dp[i][j]
的计算,我们要把结果保留下来,再下次计算的时候,如果这个位置被计算过,则直接返回结果。
总时间复杂度与一维dp无异。
总代码:
#include
#include
#include
#include
using namespace std;
int getStep(int start, int end);
int dp[N][N];
int c[N];
const int N = 1005;
const int M = 1000000007;
int main () {
int n;
cin>>n;
for (int i=0;i>c[i+1];
for (int i=1;i<=n;++i)
for (int j=1;j<=n+1;++j)
dp[i][j] = -1;
for (int i=1;i<=n+1;++i) dp[i][i] = 0;
printf("%d", getStep(1, n+1));
return 0;
}
int getStep(int start, int end) {
if (dp[start][end] != -1) return dp[start][end];
int a1 = getStep(start, end - 1);
int a2= getStep(c[end-1], end-1);
dp[start][end] = a1 + a2 + 2;
return dp[start][end]%M;
}