2017年10月18日 星期三

高血壓筆記

先看高血壓定義:

依據JNC8, 我們可依族群設定不同的血壓目標,主要分為兩種
1. 若病患大於60歲且無糖尿病以及慢性腎臟病 => 150/90 開始治療
2. 其餘情況 => 140/90 開始治療


成因:
1. primary (essential)
2. secondary

治療方式:
1. 生活型態調整(每項降收縮壓 5mmHg)

(1)  減重
(2)  有氧運動
(3)  飲食
(4)  限鹽
(5)  限酒

2. 藥物治療
=> 若病患有慢性腎臟病或高血壓, 使用ACEI/ARB, 再考慮加其他種藥
=> 其他病患依族群分類 => 黑人=> TZD or CCB , 再考慮加其他種藥
                                           => 其他族群 => TZD or ACEI or ARB or CCB, 再考慮加其他種藥

藥物作用機轉:

1. ACEI

(1)  抑制 RAA system內的 angiotensin-converting enzyme inhibitor
(2) 常見的有:

 captopril (也就是常聽到的capoten)

2. ARB
(1) 機轉類似ACEI, block RAA system 的 angiotensin receptor
(2) 常見的有 Losartan

p.s. 因為ACEI 和 ARB 機轉類似, 故不得合併使用
p.s. ACEI/ARB 有致畸胎性 => 孕婦禁用

3. β-Blockers:
(1) 氣喘患者絕對不可使用(切記切記,所以值班若不了解病人情況,降血壓請選別種,比較安全)
(2) 常見的有:

atenolol
Labetalol(trandate)
                               

4. CCB
(1) 阻斷 calcium chanel
(2) 常見的有

Amlodipine(Norvasc): 門診超常見用藥,也就是常聽到的脈優
Nicardipine(也就perdipine) => 臨床常用降血壓藥,洗腎病患也可用
adalat => 古早時期常用舌下服法來降血壓,後來發現容易降太快,導致病人collapse,現在多用口服了~

5. TZD
(1) 利尿劑 => 降低身體的volume, 導致血壓下降

reference:
1. JNC 8
2. The Massechusette General  Hospital Handbook of Internal Medicine
3. http://www.ktgh.com.tw

2017年10月15日 星期日

Octave/Matlab 介紹

Matlab 是一套理工科常用的數學軟體, 功能極端強大, 但缺點是需付費, 不過開源軟體社群開發出一套免費的軟體Octave,其指令可以涵蓋matlab, 非常好用, 下載地址:octave

p.s. 本文用>>取代原本開頭(ex. octave:1>) ,來方便簡化
其指令為 PS1('>> ')
指令教學:

1. 繪圖

(1)二維繪圖:
>> x=[1,2,4,6,8]
>> y=[3,4,6,7,9]
>> plot(x,y)

圖案如下:
其實還蠻漂亮的XD

2. vector:

(1) row vector:
>> v=[1 2 3]
v=
      1  2  3

(2) column vector:
>>v=[1;2;3]
v=
      1
      2
      3

3.  matrix 運算:
(1) matrix 宣告

>> A=[1 2 ; 3 4 ; 5 6]
A=
        1  2
        3  4
        5  6

(2) matrix transport
>> A'
A=
        1  2  3
        4  5  6

4. control statement:

(1) loop:
>> for i=1:5,
> v(i)=i;
> end;
> v
v=
      1  2  3  4  5

5.  其他功能

(1) 如果需要加註解, 利用%符號
>> 6+7   % 6 add 7
13

(2)  如果不知道這個指令如何使用,可以在指令前面加help
>> help help % 查詢help指令如何使用

(3) linux 的許多指令也能使用,例如pwd, ls, cd


reference:
1. https://www.gnu.org/software/octave/
2. Machine learning by andrew ng
3. mathwork
4. Octave

2017年10月7日 星期六

trie 介紹

trie 是一種樹狀的數據結構,用來儲存大量字串,每個節點由個一個字組成,先創原點,再將單字逐個加入,若遇到之前沒有的,則加入那個分枝

其主要應用領域在bioinformatics,information retrieval

trie可分為好幾種,以下由我一一道來

1. 26 way trie: 一個節點有26個分支,主要用在英文單字的儲存,圖解如下=>

假設有aaa,aab,efg三個單字,先創原點,用@表示
         
            先加入aaa                再加入aab           最後加入efg
            @                                   @                       @
           /                                       /                         / \
         a                                      a                        a     e
        /        =>                           /              =>       /       \
       a                                      a                        a         f
      /                                       / \                       / \         \
     a                                     a   b                   a   b         g

須注意每個節點需用一個變數來表示是否為終點,比如說上圖我們搜尋aa,也能找到,但是aa實際上不存在於我們的資料中;此外,每新增一個節點,其實我們需要新增26個指標,來指向NULL


來看trie的複雜度,假設有n個字串,字串長度最長為L,建立trie所需複雜度為O(n*L),insert的複雜度為O(L),search的複雜度亦為O(L),非常的快,且能支援prefix search, 意思為輸入前綴,有相同前綴的單字都會跑出來, 舉例來說,輸入pet,可能會跑出peter,petty之類的

另一種分析複雜度的方法,假設全部的字數為N,理想狀態下,若字串長度差不多,則insert,search,delete的complexity皆為O(log N),因為高度為log N

缺點: space complexity實在太大太大, 需要27*N(reference), 因此若搜尋筆數不多,可能使用其他方法更有效率

2. Ternary search tries(TST):

和上面的trie類似, 也是每個節點儲存一個字以及變數,但不同的是每個節點只有三個子節點,分別是左邊接值小(表示字串開始的值比目前節點小),值相等往下方走,右方值大(表示字串開始的值比目前節點大)

TST insert, 圖解=>

     先加入aaa                再加入dcb                       再加入ef
                                (d比a大,所以接右邊)        (e比a大,往下再比,又比d大,所以接右邊)                  
       a                                        a                        a     
       |                                 =>    |\              =>      |\      
       a                                       a d                     a d        
       |                                         |  |                      |  | \       
       a                                       a  c                     a c e       
                                                    |                         |   |
                                                    b                        b  f 

其實訣竅很簡單, 就是比大小XD,遇到值大右走,值小左走,值相等往下

有一點很值得提的,就是TST是由Robert Sedgewick和Jon L. Bentley在1990年代提出,
其中Robert Sedgewick 就是參考資料2的作者

複雜度分析,其實很明顯可以看出time complexity 比26-way多, 但是 space complexity 少非常多
分析如下,search 和 insert 都變成 O(L+logN),其中L是字串長度,N是總字數,原因很簡單,因為原本字串
長度就是L, logN代表最多能被多接幾個; 至於空間複雜度很簡單,就是4N(reference)


reference:
1. https://www.coursera.org/learn/gaoji-shuju-jiegou/lecture/1s2Nc/trie-shu
2. http://algs4.cs.princeton.edu/lectures/52Tries.pdf

2017年10月2日 星期一

win10 ubuntu 安裝於外接硬碟心得

如題,試了好久才成功,寫個紀錄以免忘記,我本身電腦是win10系統,最近想要使用ubuntu,但又怕裝ubuntu影響到原本系統,於是決定將ubuntu安裝在外接硬碟裡
需要物品:
USB隨身碟:用來做開機光碟
外接硬碟:用來做Ubuntu系統空間


首先.先下載ubuntu iso檔,下載網址: https://www.ubuntu.com/download/desktop

之後,下載unetbootin,將iso灌入usb檔,將usb製作成開機光碟

之後重新開機(win10要壓住F2),進入bios模式,選擇boot,將模式改為legacy(UEFI怎麼試都不成功@@),將USB FDD的順位拉到最前面,此時選擇儲存設定後開機

成功開機後,即可開始安裝ubuntu,在installation type那裡,記得要選something else,來進行磁碟分割,到達下一個頁面後,將bootloader安裝在隨身硬碟,並將隨身硬碟空間拆成swap area和ext4即可
(記得留下free space給bootloader),還有就是ext4必須mount,可以選擇 " / "


p.s. 如果之後拔掉隨身硬碟,想換回win10開機,記得bios模式要改回UEFI




reference:
1. https://blog.gtwang.org/linux/install-ubuntu-linux-to-usb-stick/

2017年9月16日 星期六

leetcode-678 Valid Parenthesis String

題意: 給定一含括弧字串,內另含*符號,可替代為  (  or  ) or 不替代

解題思路: 這題的基本概念,可先參見筆者對另一題的解法,總之就是要確保一路上左括弧都會大於等於右括弧,且最後左括弧數能等於右括弧數

可以用區間概念來處理,區間右端表示左括弧最多能比右括弧多幾個
                                                 左端表示左括弧最少能比右括弧多幾個(一定要大於等於零)

當遇到 ( 時, 區間左右端都加一
             ) 時, 區間左右端都減一
             *時, 區間左端減一,右端加一(因為可為左括弧或右括弧)
如此即可解

c++ code如下:

class Solution {
public:
    bool checkValidString(string s) {
        int top=0;
        int bottom=0;
        int len=s.length();
        for(int i=0;i<len;i++)
        {
            if(s[i]=='(')
            {
                top++;
                bottom++;
            }
            else if(s[i]==')')
            {
                top--;
                bottom--;                   
            }
            else
            {
                top++;
                bottom--;
            }
            if(top<0)
                return false;
            if(bottom<0)
                bottom=0;
        }
        if(bottom==0)
            return true;
        return false;
    }
};

leetcode-680 Valid Palindrome II

題意: 給定一字串,最多可以消去一個字,返回是否為回文字串

解題思路: 簡單,因為只能削去一個字,所以當遇到第一個不符合回文字串的字時,有兩種處理方式, 削去目前的字(即表示從下一個位置開始處理),或削去比對的另一個字,將對方處理位置減一
,考慮這兩種處理方式,即為所求

c++ code:
class Solution {
public:
    bool validPalindrome(string s) {
        int len=s.length()-1;
        int ch=len/2;
        int i;
        int ok=1;
        for(i=0;i<=ch;i++)
        {
            if(s[i]!=s[len-i])
              break;  
        }
        for(int j=i+1;j<=ch;j++)
        {
            if(s[j]!=s[len+1-j])
            {
                ok=0;
                break;
            } 
        }
        if(ok)
            return true;
        ok=1;
        for(int j=i;j<=ch;j++)
        {
            if(s[j]!=s[len-1-j])
            {
                ok=0;
                break;
            } 
        }
        if(ok)
            return true;
        return false;
        
    }
};

2017年9月15日 星期五

binary search

二分搜索說簡單也算簡單 說難也算難 有時寫不好 就會變成無窮迴圈
關鍵在哪裡呢  讓我來介紹一下巴

二分搜索的原理很簡單 就是針對以排序數列 利用比大小 每次捨去一半數列

至於為何會寫不好呢 有個小技巧可以克服 就是利用開閉區間的概念

開區間  (a,b) 意思是數會在a,b間  但不等於a 也不等於b
閉區間  [a,b] 意思是數會在a,b間  但可以等於a 也可以等於b

搞懂了這個之後  我們來看一道題: 連結
題目是從leetcode來的
題意是給一以排序數列,插入值為target的數,維持依然排序,返回插入點

先看兩端開區間寫法:
可注意到left取-1, right取總數,剛好確保為開區間

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left=-1;
        int right=nums.size();
        int mid;
        while(right-left>1)
        {
            mid=(left+right)/2;
            if(target>nums[mid])
                left=mid;
            else if(target<nums[mid])
                right=mid;
            else
                return mid;
        }
        return left+1;
    }
};

再看兩端閉區間寫法:

可注意到left取0,right取數量減一,因為允許區間和數字相等,所以取數列兩端點,
終止條件也完全不同,允許>=,因為閉區間本來就允許兩端相等,此外每次更新也不同,
left=mid+1 和 right=mid-1 因為閉區間允許相同 所以每次可往前推進一個
最後就是return的也不同 因為left是確定至少會大於等於這個數 所以返回left

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left=0;
        int right=nums.size()-1;
        int mid;
        while(right>=left)
        {
            mid=(left+right)/2;
            if(target>nums[mid])
                left=mid+1;
            else if(target<nums[mid])
                right=mid-1;
            else
                return mid;
        }
        return left;
    }
};

總結:
搞懂了以上概念後 還可以自行變化 比如說 [ ) or ( ], 原理和上面也差不多,就自己嘗試囉

leetcode-36 Valid Soduku

題意: 給定一數獨盤面,確定目前盤面是否合法

解題思路: 大水題, 依規則,橫向確認,直向確認,九宮格確認即可

C++ code:
class Solution {
public:
    int count[200];
    int count1[200];
    int square[10][10][200];
    bool isValidSudoku(vector<vector<char>>& board) {
        for(int i=0;i<9;i++)
        {
            memset(count,0,sizeof(count));
            memset(count1,0,sizeof(count));
            for(int j=0;j<9;j++)
            {
                if(board[i][j]!='.')
                {
                    if(count[board[i][j]])
                        return false;
                    if(square[i/3][j/3][board[i][j]])
                        return false;
                    square[i/3][j/3][board[i][j]]++;
                    count[board[i][j]]++;
                }
                if(count1[board[j][i]]&&board[j][i]!='.')
                    return false;
                count1[board[j][i]]++;       
            }
        }
        return true;
    }
};

leetcode-35

leetcode-34 Search Insert Position

題意: 對一內部元素不重複的已排序數列,插入數字

解題思路: 就是二分搜索,原理可見筆者文章

c++ code:

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left=-1;
        int right=nums.size();
        int mid;
        while(right-left>1)
        {
            mid=(left+right)/2;
            if(target>nums[mid])
                left=mid;
            else if(target<nums[mid])
                right=mid;
            else
                return mid;
        }
        return left+1;
    }
};

2017年9月13日 星期三

血尿臨床思路

Hematuria 在臨床上很常見   茲將臨床思路整理如下

先看病人是哪一種血尿
1.  如果是gross hematuria(肉眼可見): 考慮泌尿道問題=>
若病人無外傷或UTI=>考慮影像學檢查(CT, renal echo, IVP)=>r/o malignancy, nephrolithiasis
                                  => cystoscopy=> r/o BPH, bladder tumor

2. 若為microscopic hematuria(>=3/HPF): 先驗sediment=>確定是否真的為血尿
因為若只有驗U/A=>未必為真正血尿(可能受myoglobulin, MC影響)

=> 若sediment 亦為postive=> confirm hematuria
=>  可藉由病史詢問 , PE and U/A=> 確認是否為UTI, APN,MC, recently urological surgery影響
=> 看sediment 是否有dysmorphic RBC, RBC cast, WBC cast
=> 若有=>考慮medical renal disease=> 包括glomerulonephritis, nephrotic syndrome, AIN....
(亦需沿下面流程r/o urinary tract tumor)
=> 若無=> consider malignancy risk
=> if high risk=> CT=>r/o malignancy, nephrolithiasis
=>if low risk or contrast allergy or poor renal function=> MRI,non-contrast CT, renal echo=> r/o malignancy, nephrolithiasis

=> cystoscopy=> r/o BPH, bladder tumor


reference:
1. Harrison's principles of internal medicine
2. AUA guidelinde
3. AAFP website
4. Massachusetts pocket medicine of internal medicine









2017年9月2日 星期六

leetcode-667 Beautiful Arrangement II

題意: 給定n和k, 求出由1-n組成的array,其相鄰數的差值洽有k種

解題思路: 這題是大水題,稍微試一下就可以解決,構作 1,k+1,(k+1)-(k-1),k,..... ; 即可發現符合需求

C++code:
class Solution {
public:
    vector<int> constructArray(int n, int k) {
        vector<int>ans;
        int cur=1;
        int s=1;
        ans.push_back(1);
        for(int i=k;i>=1;i--)
        { 
            cur=cur+s*i;
            ans.push_back(cur);
            s=-s;
        }
        for(int i=k+2;i<=n;i++)
            ans.push_back(i);
        return ans;
    }
};

leetcode-33 Search in Rotated Sorted Array

題意: 在一個rotate array內找出目標值,返回index

解法:做兩次二分查找,第一次找出rotate的點,第二次找出目標值,複雜度O(log n)

我的解法是第一次利用nums[i]>nums[i+1]來判別,但缺點是有時array根本沒被rotate,因此須設定count,若count超過特定值,則中斷,得知array未被rotate,第二次則為一般二分查找

leetcode上有人有更簡潔寫法,第一次查找找出最小值,第二次利用二分查找加移位


我的解法c++ code:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        
        int len=nums.size();
        int left=0;
        int right=len-1;
        int mid=(left+right)/2;
        if(len==0)
            return -1;
        if(len==1)
        {
            if(nums[0]==target)
                return 0;
            else
                return -1;
        }
        int count=0;
        while(nums[mid]<nums[mid+1])
        {
            if(nums[mid]<nums[len-1])
                right=mid-1;
            else
                left=mid+1;
            mid=(left+right)/2;
            count++;
            if(count>100)
                break;
        }
        if(target>nums[0])
        {
            right=mid;
            left=0;
        }
        else
        {
            if(target<nums[0])
            {
                left=mid+1;
                right=len-1;
            }
            else
                return 0;                
        }
        if(count>100)
        {
            left=0;
            right=len-1;
        }
        mid=(left+right)/2;
        count=0;
        while(nums[mid]!=target)
        {
            if(nums[mid]>target)
                right=mid;
            else
                left=mid+1;
            mid=(left+right)/2;
            count++;
            if(count>100)
                return -1;
        }
        return mid;
    }
};

leetcode-32 Longest Valid Parentheses

leetcode-31 Next Permutation

待補

2017年8月31日 星期四

leetcode-30 Substring with Concatenation of All Words

題意: 給定一個string s, 另外給定許多同樣長度的words, 求出所有s中的位置,其後的連續序列會包含所有words(中間不能有其他字符)

解題思路: 這題很難, 我的解法效率也不算太高,但還是先貼,我的解法是這樣,先用map求出同樣的word出現幾次,再利用KMP,求出所有word的出現點,之後一個位置一個位置的掃描,即可得解

class Solution {
public:
    int index[100000];
    int pre[100000];
    int check[10000];
    vector<int>ans;
    vector<int> findSubstring(string s, vector<string>& words) {
        memset(check,0,sizeof(check));
        int len=s.size();
        int num=words.size();
        int len1=words[0].size();
        map <string,int> re;
        for(int i=0;i<num;i++)
        {
           
            if(re[words[i]]==0)
                re[words[i]]=i+1;
            check[re[words[i]]]++;
            strStr(s,words[i],re[words[i]]);
            //cout<<re[words[i]]<<" "<<check[re[words[i]]]<<endl;
        }
        len=len-num*len1+1;
        
        for(int i=0;i<len;i++)
        {
            //cout<<index[i]<<endl;
            int arr[10000];
            int count=0;
            memset(arr,0,sizeof(arr));
            for(int j=0;j<num;j++)
            {
                //cout<<index[i+j*len1]<<endl; 
                if((arr[index[i+j*len1]]<check[index[i+j*len1]])&&index[i+j*len1])
                    count++;
                 arr[index[i+j*len1]]++;
            }
            if(count==num)
                ans.push_back(i);
        }
        return ans;
    }
   
    void strStr(string haystack, string needle,int k) {
          int target=haystack.size();
          int target1=needle.size();
          if(target1==0)
              return; 
          int q=-1;
          pre[0]=-1;
          for(int i=1;i<target1;i++)
          {
              while(needle[i]!=needle[q+1]&&q>-1)
                  q=pre[q];
              if(needle[i]==needle[q+1])
                  q++;
              pre[i]=q;
          }
          q=-1;
          for(int i=0;i<target;i++)
          {
              while(haystack[i]!=needle[q+1]&&q>-1)
                  q=pre[q];
              if(haystack[i]==needle[q+1])
              {
                  q++;
                  if(q==target1-1)
                       index[i-target1+1]=k;
              }
          }
    }
};

leetcode-29 Divide Two Integers

題意: 實現除法,但不能使用乘法,除法或mod

解題思路: 這題應該是為了模擬某些平台,不能使用上述指令的情況,所以利用bit manipulation來實現二進位除法, 演算法如下=>
x/y, 把y做left shift,到超過x為止,將左移的量減一,而後加到答案裡,再把x減去y左移減一的量,以此類推

ps. 須注意 加減號比左右移符號更優先,故該使用括號的時候就要用XD
可參考: MSDN

C++  code:

class Solution {
public:
    int divide(int dividend, int divisor) {
        long long ans=0;
        long long ok=1;
        long long m=(long long)dividend;
        long long n=(long long)divisor;
        if(m<0)
        {
            ok=~ok+1;
            m=~m+1;
        }
        if(n<0)
        {
            ok=~ok+1;
            n=~n+1;
        }
        
        while(m>=n)
        {
            long long t=0;
            long long c=n;
            
            while(m>=c)
            {
                t++;
                c=c<<1;
            }
            t--;
            ans=ans+((long long)1<<t);
            m=m-(n<<t);
        }
        
        if(ok==-1)
            ans=~ans+1;
        if(ans>INT_MAX||ans<INT_MIN)
            return INT_MAX;
        else
            return ans;
    }
};

2017年8月28日 星期一

leetcode-28 Implement strStr()

題意: 做字符串比對,輸出第一個符合的位置

解法: 這題就是問KMP實現了,原理可看筆者先前文章

C++ code:
class Solution {
public:
    int index[100000];
    int pre[100000];
    int strStr(string haystack, string needle) {
          int target=haystack.size();
          int target1=needle.size();
          if(target1==0)
              return 0; 
          int q=-1;
          pre[0]=-1;
          for(int i=1;i<target1;i++)
          {
              while(needle[i]!=needle[q+1]&&q>-1)
                  q=pre[q];
              if(needle[i]==needle[q+1])
                  q++;
              pre[i]=q;
          }
          q=-1;
          for(int i=0;i<target;i++)
          {
              while(haystack[i]!=needle[q+1]&&q>-1)
                  q=pre[q];
              if(haystack[i]==needle[q+1])
              {
                  q++;
                  if(q==target1-1)
                      return i-target1+1;
              }
          }
          return -1;  
    }
};

2017年8月24日 星期四

leetcode-27 Remove Element

題意: 給定一個array, 將其中和給定值相同的元素剔除

解題思路: 這題和上題的解題思路相同,都是利用兩個變數掃描array,遇到和給定值不同的就取代,即所求

c++ code:
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int len=nums.size();
        int pos=0;
        for(int i=0;i<len;i++)
        {
            if(nums[i]!=val)
            {
                nums[pos]=nums[i];
                pos++;
            }
        }
        return pos;   
    }
};

2017年8月23日 星期三

leetcode-26 Remove Duplicates from Sorted Array

題意: 給定一排序好的array, 將其重複元素剔除,要求空間複雜度為O(1)

解題思路: 這題題目出得很容易讓人誤會啊= =,返回的是int,其實判定的是array,但因為array是用reference 傳進來的,所以直接修改即可, 方法就是利用兩個變數,一個沿array走,如果遇到和前面不重複的,則把另一個變數加一,並做取代,因為第一個變數走的至少會和第二個變數一樣快,所以此算法成立

C++ code:

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int len=nums.size();
        if(len==0)
            return 0;
        int count=1;
        
        for(int i=1;i<len;i++)
        {
            if(nums[i]!=nums[i-1])
            {
                nums[count]=nums[i];
                count++;
            }
        }
        return count;
    }
};

2017年8月22日 星期二

git 指令整理

git 是一個非常流行的版本控制系統(version control system),何謂版本控制系統呢?
就是我們在程式開發時,常常會遇到一種情形,就是不知道更動這段程式碼會發生甚麼bug,有時加了一些新功能後,才發現bug跑出來,於是想回到之前的版本,這時版本控制系統就派上用場了!
以上是單人開發時的情況,多人開發時情況更複雜,常常會有檔案蓋來蓋去,不知道對方做了甚麼,這時版本控制系統就更重要了啊!

git 內部有三個結構

Working tree  ----> staged area ---> repository(內有commit)
                     git add                 git commit
為何要有staged area呢,這是因為如果沒有staged area的話,你對working tree內做的所有改變就會在你commit後,全部跑到repository內,為了更好的做到版本控制,所以才會有staged area

git 還有一個重要概念: branch
在中文裡,branch是分支的意思,在程式設計時,如果我們想實驗程式碼,又不想動到目前的程式碼,可以新增一個新的branch,指令如下: git branch  branch名稱


以下是git 的常見指令整理:

1. git clone :複製檔案
可從網路連結抓取檔案

2. git init: 在目前的位置建立一個新的repository

3. git log : 把目前repository 的所有commit 歷史都叫出來,但有時會太長,可按q跳出

4. git status: 顯示work tree 的歷史

5. git branch: 產生新的branch(但並未轉至這個branch,若須轉到這個branch,要用git checkout)

6. git checkout : 將目前檔案回到某個commit狀態 or 轉換到某個branch

7. git diff :有三種用法

(1) git diff  commit ID1 commit ID2 :比較兩個commit的不同
(2) git diff : 比較  working tree 和 staged area
(3) git diff --stage: 比較 staged area 和most recently commit

8. git merge: 合併branch和master =>可能會產生merge conflict=>需手動處理

merge conflict: 大家動到同一個檔案 電腦不知道誰的才是對的

reference:
1. udacity
2. git help
3. https://git-scm.com/docs/git-merge

leetcode-25 Reverse Nodes in k-Group

題意: 其實是上一題(k=2)的延伸版,就是給定一個linked list, 每k個元素要反轉,若不足k個則不用,空間複雜度須為O(1)

解題思路:想法簡單,實現起來不容易,訣竅就是每數到k個元素時反轉,反轉利用三個指標,分別記錄連續三個元素,之後依此類推,須注意邊界條件處理,以免發生null pointer exception

C++ code:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        
        ListNode* ori=new ListNode(0);
        int count=0;
        if(head==NULL||k==1)
            return head;
        ListNode* e;
        ListNode* o=ori;
        while(head!=NULL)
        {
           
            count++;
            if(count==1)
            {
                e=head;
                o->next=head;
            }
            if(count==k)
            {
                
                o->next=head;
                o=e;
                head=head->next;
                ListNode* temp0=e;
                ListNode* temp=e->next;
                ListNode* temp1=temp->next;
                while(count!=1)
                {
                    temp->next=temp0;
                    temp0=temp;
                    if(count!=1)//avoid access null
                        temp=temp1;
                    if(count!=2)//avoid access null
                        temp1=temp1->next;
                    count--;
                }
                o->next=NULL;
                count--;
                continue;
            }
            head=head->next;
        }
        return ori->next;
    }
};