剑指 Offer II 097. 子序列的数目(115. 不同的子序列)
题目:


思路:
【1】动态规划的方式
代码展示:
动态规划的方式(一维数组):
//利用两个一维数组轮流交替达到二维数组的效果 //时间4 ms击败86.35% //内存42.6 MB击败80.32% class Solution { public int numDistinct(String s, String t) { if(t.length() > s.length()) return 0; // s长度小于t时间直接返回0 int ns = s.length(), nt = t.length(); int[] pre = new int[nt + 1], cur = new int[nt + 1]; char[] chss = s.toCharArray(), chst = t.toCharArray(); pre[0] = 1; cur[0] = 1; // 当t为空串时,此行是必须的 for(int i = 1; i <= ns; i++){ for(int j = 1; j <= nt; j++){ if(chss[i - 1] == chst[j - 1]) cur[j] = pre[j - 1] + pre[j]; else cur[j] = pre[j]; } pre = Arrays.copyOf(cur, nt + 1); // for(int k = 0; k <= nt; k++) pre[k] = cur[k]; } return cur[nt]; } } //只是用一维数组的变量方式 //时间2 ms击败99.51% //内存39.6 MB击败87.58% class Solution { public int numDistinct(String s, String t) { if(s.length() < t.length()) return 0; // s长度小于t时,s中不会出现t int ns = s.length(), nt = t.length(); char[] chss = s.toCharArray(), chst = t.toCharArray(); int[] dp = new int[nt + 1]; dp[0] = 1; int pre = dp[0]; for(int i = 1; i <= ns; i++){ for(int j = 1; j <= nt; j++){ int nextPre = dp[j]; // 相当于二维矩阵中待更新的dp[i][j]的dp[i - 1][j - 1] if(chss[i - 1] == chst[j - 1] ) dp[j] += pre; pre = nextPre; } pre = 1; // 每完成一行要重置该值为1 } return dp[nt]; } }
动态规划的方式(二维数组):
//二维数组的辅助变量(正序) //时间4 ms击败86.35% //内存43.6 MB击败80.7% class Solution { public int numDistinct(String s, String t) { if(s.length() < t.length()) return 0; // s长度小于t时,s中不会出现t int ns = s.length(), nt = t.length(); char[] chss = s.toCharArray(), chst = t.toCharArray(); int[][] dp = new int[ns + 1][nt + 1]; for(int i = 0; i <= ns; i++) dp[i][0] = 1; for(int i = 1; i <= ns; i++){ for(int j = 1; j <= nt; j++){ dp[i][j] = dp[i - 1][j] + (chss[i - 1] == chst[j - 1] ? dp[i - 1][j - 1] : 0); } } return dp[ns][nt]; } } //二维数组的辅助变量(逆序) //时间10 ms击败81.42% //内存45.7 MB击败92.78% class Solution { public int numDistinct(String s, String t) { int m = s.length(), n = t.length(); if (m < n) { return 0; } int[][] dp = new int[m + 1][n + 1]; for (int i = 0; i <= m; i++) { dp[i][n] = 1; } for (int i = m - 1; i >= 0; i--) { char sChar = s.charAt(i); for (int j = n - 1; j >= 0; j--) { char tChar = t.charAt(j); if (sChar == tChar) { dp[i][j] = dp[i + 1][j + 1] + dp[i + 1][j]; } else { dp[i][j] = dp[i + 1][j]; } } } return dp[0][0]; } }

浙公网安备 33010602011771号