第13天--演算法(機器人問題,紙牌問題,Morris遍歷)
1.機器人問題,一共有1-N N個位置,機器人可以在1-N上任意移動,初始位置為start,目標位置為aim,可以移動K次,求有幾種移動方式
(1)遞迴實現
public int ways3(int N,int start,int aim,int K) {
return process3(start,K,aim,N);
}
public int process3(int cur,int rest,int aim,int N) {
if(rest == 0) {
return cur == aim ? 1 : 0;
}else if(cur == 1) {
return process3(2,rest - 1,aim,N);
}else if(cur == N) {
return process3(N - 1,rest - 1,aim,N);
}else {
return process3(cur + 1,rest - 1,aim,N) + process3(cur - 1,rest - 1,aim,N);
}
}
(2)動態規劃實現
public int ways3(int N,int start,int aim,int K) {
int dp[][] = new int[N + 1][K + 1];
dp[aim][0] = 1;
for(int rest = 1;rest <= K;rest ++) {
dp[1][rest] = dp[2][rest - 1];
dp[N][rest] = dp[N - 1][rest - 1];
for(int cur = 2;cur <= N - 1;cur ++) {
dp[cur][rest] = dp[cur + 1][rest - 1] + dp[cur - 1][rest - 1];
}
}
return dp[start][K];
}
2.紙牌問題,紙牌以陣列中數字呈現,每個人都只能拿最左或最右的牌,返回先手拿牌的最大值和後手拿牌的最大值
(1)遞迴實現
public int processA(int arr[],int L,int R) {
if(L == R) {
return arr[L];
}
int p1 = arr[L] + processB(arr,L + 1,R);
int p2 = arr[R] + processB(arr,L,R - 1);
return Math.max(p1,p2);
}
public int processB(int arr[],int L,int R) {
if(L == R) {
return 0;
}
int p1 = processA(arr,L + 1,R);
int p2 = processA(arr,L,R - 1);
return Math.min(p1,p2);
}
(2)動態規劃實現
public static void main(String[] args) {
int arr[] = {5,7,4,5,8,1,6,0,3,4,6,1,7};
int N = arr.length;
int dpA[][] = new int[N][N];
int dpB[][] = new int[N][N];
for(int L = 0;L < N;L ++) {
dpA[L][L] = arr[L];
}
for(int L = N - 2;L >= 0;L --) {
for(int R = L + 1;R <= N - 1;R ++) {
int p1 = arr[L] + dpB[L + 1][R];
int p2 = arr[R] + dpB[L][R - 1];
dpA[L][R] = Math.max(p1,p2);
int p3 = dpA[L + 1][R];
int p4 = dpA[L][R - 1];
dpB[L][R] = Math.min(p3,p4);
}
}
System.out.println(dpA[0][arr.length - 1]);
System.out.println(dpB[0][arr.length - 1]);
}
3.Morris遍歷
(1)正常遞迴遍歷(前序)
public void process(Node head) {
if(head == null) {
return;
}
System.out.println(head.val);
process(head.left);
process(head.right);
}
(2)Morris遍歷
public void morrisPre(Node head) {
if(head == null) {
return;
}
Node cur = head;
Node mostRight = null;
while(cur != null) {
mostRight = cur.left;
if(mostRight != null) {
while(mostRight.right != null && mostRight.right != cur) {
mostRight = mostRight.right;
}
if(mostRight.right == null) {
System.out.print(cur.val + " ");
mostRight.right = cur;
cur = cur.left;
continue;
}else {
mostRight.right = null;
}
}else {
System.out.print(cur.val + " ");
}
cur = cur.right;
}
}