I recently was solving a problem in leetcode.
My first submission -
class Solution {
public int knightDialer(int n) {
int[] prev_dp = new int[10];
int[] curr_dp = new int[10];
int mod = 1000000007;
List<List<Integer>> adjList = new ArrayList<>();
adjList.add(new ArrayList<>(Arrays.asList(4,6)));
adjList.add(new ArrayList<>(Arrays.asList(6,8)));
adjList.add(new ArrayList<>(Arrays.asList(7,9)));
adjList.add(new ArrayList<>(Arrays.asList(4,8)));
adjList.add(new ArrayList<>(Arrays.asList(0,3,9)));
adjList.add(new ArrayList<>(Arrays.asList()));
adjList.add(new ArrayList<>(Arrays.asList(0,1,7)));
adjList.add(new ArrayList<>(Arrays.asList(2,6)));
adjList.add(new ArrayList<>(Arrays.asList(1,3)));
adjList.add(new ArrayList<>(Arrays.asList(2,4)));
if(n==0) return 0;
// for 1st step;
for(int i = 0; i<10;i++){
curr_dp[i] = 1;
}
// prev_dp = curr_dp.clone();
System.arraycopy(curr_dp,0, prev_dp,0,10);
for(int j = 2; j<=n;j++){
for(int i = 0; i<10;i++){
int curr_sum = 0;
for(int adjNode: adjList.get(i)){
curr_sum+=prev_dp[adjNode];
curr_sum = curr_sum%mod;
}
curr_dp[i] = curr_sum;
}
// prev_dp = curr_dp.clone();
System.arraycopy(curr_dp,0, prev_dp,0,10);
}
int ans = 0;
for(int i = 0; i<10;i++){
ans+=curr_dp[i];
ans = ans%mod;
}
return ans;
}
}
My second submission -
class Solution {
public int knightDialer(int n) {
int[] prev_dp = new int[10];
int[] curr_dp = new int[10];
int mod = 1000000007;
List<List<Integer>> adjList = new ArrayList<>();
adjList.add(new ArrayList<>(Arrays.asList(4,6)));
adjList.add(new ArrayList<>(Arrays.asList(6,8)));
adjList.add(new ArrayList<>(Arrays.asList(7,9)));
adjList.add(new ArrayList<>(Arrays.asList(4,8)));
adjList.add(new ArrayList<>(Arrays.asList(0,3,9)));
adjList.add(new ArrayList<>(Arrays.asList()));
adjList.add(new ArrayList<>(Arrays.asList(0,1,7)));
adjList.add(new ArrayList<>(Arrays.asList(2,6)));
adjList.add(new ArrayList<>(Arrays.asList(1,3)));
adjList.add(new ArrayList<>(Arrays.asList(2,4)));
if(n==0) return 0;
// for 1st step;
for(int i = 0; i<10;i++){
curr_dp[i] = 1;
}
// prev_dp = curr_dp.clone();
// System.arraycopy(curr_dp,0, prev_dp,0,10);
for(int i = 0; i<10;i++){
prev_dp[i] = curr_dp[i];
}
for(int j = 2; j<=n;j++){
for(int i = 0; i<10;i++){
int curr_sum = 0;
for(int adjNode: adjList.get(i)){
curr_sum+=prev_dp[adjNode];
curr_sum = curr_sum%mod;
}
curr_dp[i] = curr_sum;
}
// prev_dp = curr_dp.clone();
// System.arraycopy(curr_dp,0, prev_dp,0,10);
for(int l = 0; l<10;l++){
prev_dp[l] = curr_dp[l];
}
}
int ans = 0;
for(int i = 0; i<10;i++){
ans+=curr_dp[i];
ans = ans%mod;
}
return ans;
}
}
First submission is considerably faster(~3 times) and consume very less memory(~1/4) from the second submission.
My questions are -
- Why clone and system.arraycopy are slower than copying elements with loop?
- Why clone and system.arraycopy take this much extra memory than copying elements with loop?