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?
 
    