递归算法的简单应用

为了确保递归函数不会导致无限循环,它应具有以下属性:

  • 一个简单的基本案例(basic case)(或一些案例) —— 能够不使用递归来产生答案的终止方案。
  • 一组规则,也称作递推关系(recurrence relation),可将所有其他情况拆分到基本案例。

1、以相反的顺序打印字符串

/**
   输入:["h","e","l","l","o"]
   输出:["o","l","l","e","h"]
 */
public class PrintReverseDemo {

    public static void main(String[] args) {
        printReverse("apple".toCharArray());
    }

    private static void printReverse(char[] str) {
        helper(0, str);
    }

    private static void helper(int index, char[] str) {

        if (null == str || index >= str.length) {
            return;
        }
        helper(index + 1, str);
        System.out.print(str[index]);
    }
}

 

2、两两交换链表中的节点

/**
 * 给定 1->2->3->4, 你应该返回 2->1->4->3.
 */
public class SwapNodeDemo {

    public static void main(String[] args){

        ListNode head = makeListNode();

        System.out.println(head);
        System.out.println(swapPairs2(head));
}


    /**
     * 递归
     * @param head
     * @return
     */
    public static ListNode swapPairs(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        
        ListNode p = head.next;
        head.next = swapPairs(head.next.next);
        p.next = head;
        return p;
    }

    /**
     * 非递归
     * @param head
     * @return
     */
    public static ListNode swapPairs2(ListNode head) {
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode curr = dummy;
        while (curr.next != null && curr.next.next != null) {
            ListNode first = curr.next;
            ListNode second = curr.next.next;

            // swap two nodes
            first.next = second.next;
            second.next = first;
            curr.next = second;

            // update to next iteration
            curr = curr.next.next;
        }
        return dummy.next;
    }

    public static ListNode makeListNode() {
        ListNode one = new ListNode(1);
        ListNode two = new ListNode(2);
        ListNode three = new ListNode(3);
        ListNode four = new ListNode(4);

        one.next = two;
        two.next = three;
        three.next = four;

        return one;
    }

 

3、杨辉三角

给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。在杨辉三角中,每个数是它左上方和右上方的数的和。

 

public List<List> generate(int numRows) {
        List<List> result = new ArrayList<>();
        if(numRows <= 0){
            return result;
        }

        for(int i=1;i<= numRows; i++){
            List innerList = new ArrayList<>();
            for(int j=1;j<=i;j++){
                innerList.add(f(i,j));
            }
            result.add(innerList);
        }
        return result;
    }

    public int f(Integer i,Integer j){
        if(j == 1 || i == j){
            return 1;
        }else{
            return f(i-1,j-1) + f(i-1,j);
        }
    }

 

4、给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 行。算法到 O(k) 空间复杂度。

 public List getRow(int rowIndex) {
        List result = new ArrayList();
        long num = 1;
        for (int i = 0; i <= rowIndex; i++) {
            result.add((int) num);
            num = num * (rowIndex - i) / (i + 1);
        }
        return result;
    }

 

posted @ 2019-08-25 10:06  kaleidoscopic  阅读(485)  评论(0编辑  收藏  举报