1. 程式人生 > 其它 >把遞迴拆出來理解

把遞迴拆出來理解

這兩天寫幾個遞迴演算法題有點心得,記錄一下

先說結論

遞迴過程:(判斷條件)-進入--操作-(判斷條件)-退出

rec(a){
if(滿足退出)-退出
操作
rec(a)
(操作)
}

從連結串列逆序開始

// 獲取節點所在位置,逆序
public int length(ListNode node, int n) {
    if (node == null)
        return 0;
    int pos = length(node.next, n) + 1;
    //獲取要刪除連結串列的前一個結點,就可以完成連結串列的刪除
    if (pos == n + 1)
        node.next = node.next.next;
    return pos;
}

拆開

// 獲取節點所在位置,逆序
public int length(ListNode node, int n) {
    if (node == null)
        return 0;
    int pos = length(ListNode node, int n) {
                    if (node == null)//exit
                        return 0;/////exit
                    int pos = length(ListNode node, int n) {
                        if (node == null)//exit
                        	 return 0;/////exit
                        int pos = length(node.next, n){...} + 1;
                       
                    }+ 1;
                    	.
                        .
                        .
                  }+1
    
    
    
    //獲取要刪除連結串列的前一個結點,就可以完成連結串列的刪除
    if (pos == n + 1)
        node.next = node.next.next;
    return pos;
}

達到出口條件

// 獲取節點所在位置,逆序
public int length(ListNode node, int n) {
    if (node == null)
        return 0;
    int pos = length(ListNode node, int n) {
                    if (node == null)//exit
                        return 0;/////exit
                    int pos = length(ListNode node, int n) {
                        if (node == null)//exit
                        	 return 0;/////exit
                        int pos = length(node.next, n){...//pos=pos+1	|6
                            if (node == null)//exit
                        		return 0;/////exit
                   			int pos = length(ListNode node, int n) {//	|3.2
                        	if (node == null)//true   					|1
                        		 return 0;/////exit 0 					|2
                                                      } + 1; //pos =0+1 |3.1
                                if (pos == n + 1)//		false			|4
    							    node.next = node.next.next;
    							return pos;				//return 0		|5
                       
                    }+ 1;
                    	.
                        .
                        .
                  }+1
    
    
    
    //獲取要刪除連結串列的前一個結點,就可以完成連結串列的刪除
    if (pos == n + 1)
        node.next = node.next.next;
    return pos;
}

判斷迴文連結串列

ListNode temp;

public boolean isPalindrome(ListNode head) {
    temp = head;
    return check(head);
}

private boolean check(ListNode head) {
    if (head == null)
        return true;
    boolean res = check(head.next) && (temp.val == head.val);
    temp = temp.next;
    return res;
}

拆開

ListNode temp;

public boolean isPalindrome(ListNode head) {
    temp = head;
    return check(head);
}

private boolean check(ListNode head) {
    if (head == null)
        return true;
    boolean res = check(head.next){
        if (head == null)
            return true;
        boolean res = check(head.next){
            if (head == null)
                return true;
            boolean res = /*check(head.next)*/true && (temp.val == head.val);//reach exit 1
            temp = temp.next;												//下一個 		2
            return res;														//返回上級	   3
        } && (temp.val == head.val);										//判斷		4
        temp = temp.next;
        return res;
    } && (temp.val == head.val);
    temp = temp.next;
    return res;
}

雖然這個題遞迴會重複計算一次,但是這個遞歸屬於看得懂很難想出來