20181111_ARTS_W6

第六周arts

Algorithm

看專欄《數(shù)據(jù)結構與算法之美》遇到的一道算法題:
題目描述:給定一個單鏈表連接的字符串,判斷是不是回文字符串
比如:

  • a->b->c->b->a 是
  • a->b->b->a 是
  • a->b->c 否

思路分析:

  • 如果是普通的字符串則很好判斷,利用數(shù)組的訪問為O(1)+ 對稱性即可判斷
  • 單鏈表則不能這么做,我的思路:
    思路1:將鏈表逆序之后與原鏈表對比:需要先將原鏈表拷貝一份(如何copy),然后逆序
    思路2:快慢指針找到中間節(jié)點,然后逆序前半部分鏈表,之后遍歷比較前后兩部分鏈表即可,最后將鏈表前半部分逆序還原, 具體思路見代碼注釋。

具體代碼實現(xiàn)如下:

public class PalidromeString {

    public static void main(String[] args) {
        PalidromeString ps = new PalidromeString();
        Node head = new Node('1');
//        Node p1 = head.next = new Node('1');
//        Node p2 = p1.next = new Node('2');
//        Node p3 = p2.next = new Node('1');
//        Node p4 = p3.next = new Node('1');
        System.out.println(ps.isPalidromeString2(head));
    }

    //思路1:時間復雜度:O(n),空間復雜度:O(n)
    public boolean isPalidromeString(Node head) {

        if (head == null) {
            return true;
        }

        //copy head 這里假設head是包含元素的
        Node copyHead = new Node(head.val);
        Node originP = head.next, copyP = copyHead;
        while (originP != null) {
            copyP.next = new Node(originP.val);

            originP = originP.next;
            copyP = copyP.next;
        }

        //reverse copyHead
        Node p = copyHead, q = p.next;
        while (q != null) {
            p.next = q.next;
            q.next = copyHead;

            //更新
            copyHead = q;
            q = p.next;
        }

        //開始比較
        originP = head;
        copyP = copyHead;
        while (originP != null && copyP != null) {
            if (originP.val != copyP.val) {
                return false;
            }
            originP = originP.next;
            copyP = copyP.next;
        }

        return true;
    }

    /**
     * 思路2:快慢指針,先找到中間節(jié)點,然后將前半段逆序,然后分別從開頭和中間順序比較,最后將前半段逆序還原(一般實現(xiàn)是不改變輸入)
     * 時間復雜度O(n),空間復雜度O(1)
     * 注意點:找中間節(jié)點或者比較時,與鏈表中的個數(shù)是偶數(shù)還是奇數(shù)是息息相關的,注意區(qū)分對待;尤其要注意空指針的判斷
     * 比如:
     * 偶數(shù)個:1->2->2->1, 中間節(jié)點mid這里取第二個2(當然如果取第一個2也可以,但是后面的逆序條件判斷需要變化),
     * 逆序p,q,當q==mid時停止逆序,可以保證只有前半段逆序,比較指針:head, mid即可,逆序回去呢,同理
     * 奇數(shù)個:1->2->3->2->1, 中間節(jié)點mid為3,逆序p,q,也可以q==mid的時候停止逆序,則逆序之后為2->1->3->2->1,比較:head,mid.next開始比較
     * 逆序回去呢,同理
     * 上述分析可以保證偶數(shù),奇數(shù)保持統(tǒng)一
     */

    public boolean isPalidromeString2(Node head) {
        if (head == null) {
            return true;
        }

        //按照上述分析,利用快慢指針找出符合條件的中間節(jié)點,最后慢指針指向的就是中間節(jié)點
        Node slow = head, fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        Node mid = slow;

        //前半段逆序
        Node p = head, q = p.next;
        while (q != null && q != mid) {
            p.next = q.next;
            q.next = head;

            //更新
            head = q;
            q = p.next;
        }

        //開始比較,奇數(shù):head,mid.next(注意只有一個元素時), 偶數(shù):head, mid
        Node start1 = head, start2;
        if (fast == null) {
            //說明是偶數(shù)個元素
            start2 = mid;
        } else {
            start2 = mid.next;
        }
        //這樣判斷可以很好的避免只有一個元素的誤判
        boolean isPalidromeString = true;
        while(start1 != null && start2 != null){
            if(start1.val != start2.val){
                isPalidromeString = false;
                break;
            }
            start1 = start1.next;
            start2 = start2.next;
        }

        //還原前半段逆序的元素
        p = head;
        q = p.next;
        while (q != null && q != mid) {
            p.next = q.next;
            q.next = head;

            //更新
            head = q;
            q = p.next;
        }

        return isPalidromeString;
    }
}

class Node {
    Node next = null;
    char val;

    public Node(char val) {
        this.val = val;
    }

}
Review

繼續(xù)微服務相關的英文文章:
關于nginx上的introduction-to-microservices的系列文章,讀書筆記鏈接:http://www.itdecent.cn/p/fd47ae1917dc

Tip

使用Spring事務的時候遇到的一個坑:在加了Spring事務的函數(shù)里面涉及對同一個數(shù)據(jù)庫多個表的插入操作,發(fā)現(xiàn)某個表的插入記錄失敗后,之前插入其他表的數(shù)據(jù)竟然成功了。
造成的原因:在事務函數(shù)中加了try...catch,直接把數(shù)據(jù)庫異常給catch掉了,導致Spring不知道要回滾。Spring的回滾機制:在事務層拋出異常時,Spring會做回滾標記,所以不能在事務層try...catch, try...catch應該放在調(diào)用事務函數(shù)的地方。

Share

一直在分享這一塊不知道寫什么,就分享下最近激勵自己的一句話吧。
自律給你自由,自由是什么?自由不是你想干什么就干什么,而是不想干什么就不干什么,所以從堅持arts, 堅持運動開始,把優(yōu)秀當成一種習慣。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容