[劍指offer]刷題筆記


  • 兩個(gè)鏈表的第一個(gè)公共結(jié)點(diǎn)

  • 數(shù)組中只出現(xiàn)一次的數(shù)字

  • 和為S的連續(xù)正序列

  • 和為S的兩個(gè)數(shù)字(與上題類似)


兩個(gè)鏈表的第一個(gè)公共結(jié)點(diǎn)

題目描述:輸入兩個(gè)鏈表墩朦,找出它們的第一個(gè)公共結(jié)點(diǎn)扰柠。(注意因?yàn)閭魅霐?shù)據(jù)是鏈表囤热,所以錯(cuò)誤測(cè)試數(shù)據(jù)的提示是用其他方式顯示的,保證傳入數(shù)據(jù)是正確的)

我的方法(太笨了)

class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        ListNode* p=pHead1;
        ListNode* q=pHead2;
        for(p=pHead1;p!=NULL;p=p->next)
        {
            for(q=pHead2;q!=NULL;q=q->next)
            {
                if(q==p)
                    return p;
            }
        }
        return NULL;
    }
};

更好的方法:找差值

class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        ListNode* p1=pHead1;
        ListNode* p2=pHead2;
        int len1=getLength(pHead1);
        int len2=getLength(pHead2);
        int len=0;  //第一個(gè)鏈表和第二個(gè)鏈表的差值
        
        if(len1>=len2)  //第一個(gè)鏈表比第二個(gè)長(zhǎng) 第一個(gè)鏈表先走差值
        {
            len=len1-len2;
            while(len>0)
            {
                p1=p1->next;
                len--;
            }
        }
        else  //第二個(gè)鏈表比第一個(gè)長(zhǎng) 第二個(gè)鏈表先走完差值
        {
            len=len2-len1;
            while(len>0)
            {
                p2=p2->next;
                len--;
            }
        }
        while(p1!=p2)
        {
            p1=p1->next;
            p2=p2->next;
        }
        return p1;
    }
    int getLength(ListNode* p)
    {
        int len=0;
        ListNode* current=p;
        while(current!=NULL)
        {
            len++;
            current=current->next;
        }
        return len;
    }
};

長(zhǎng)度相同有公共結(jié)點(diǎn)瞎领,第一次就遍歷到;沒(méi)有公共結(jié)點(diǎn),走到尾部NULL相遇怎棱,返回NULL;長(zhǎng)度不同有公共結(jié)點(diǎn),第一遍差值就出來(lái)了绷跑,第二遍一起到公共結(jié)點(diǎn)拳恋;沒(méi)有公共,一起到結(jié)尾NULL砸捏。

class Solution {
public:
   ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
       /*
        假定 List1長(zhǎng)度: a+n  List2 長(zhǎng)度:b+n, 且 a<b
        那么 p1 會(huì)先到鏈表尾部, 這時(shí)p2 走到 a+n位置,將p1換成List2頭部
        接著p2 再走b+n-(n+a) =b-a 步到鏈表尾部,這時(shí)p1也走到List2的b-a位置谬运,還差a步就到可能的第一個(gè)公共節(jié)點(diǎn)隙赁。
        將p2 換成 List1頭部,p2走a步也到可能的第一個(gè)公共節(jié)點(diǎn)梆暖。如果恰好p1==p2,那么p1就是第一個(gè)公共節(jié)點(diǎn)伞访。  或者p1和p2一起走n步到達(dá)列表尾部,二者沒(méi)有公共節(jié)點(diǎn)轰驳,退出循環(huán)厚掷。 同理a>=b. 
        時(shí)間復(fù)雜度O(n+a+b)
       
       */
        ListNode* p1 = pHead1;
        ListNode* p2 = pHead2;
        while(p1 != p2) {
            if(p1 != NULL) p1 = p1->next;    
            if(p2 != NULL) p2 = p2->next;
            if(p1 != p2) {                   
                if(p1 == NULL) p1 = pHead2;
                if(p2 == NULL) p2 = pHead1;
            }
        }
        return p1;
     
}
        
};

數(shù)組中只出現(xiàn)一次的數(shù)字

題目描述:一個(gè)整型數(shù)組里除了兩個(gè)數(shù)字之外,其他的數(shù)字都出現(xiàn)了兩次级解。請(qǐng)寫程序找出這兩個(gè)只出現(xiàn)一次的數(shù)字冒黑。

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        map<int,int> mp;
        vector<int> res;
        for(int i=0;i<data.size();i++)
        {
            mp[data[i]]++;
        }
        for(int i=0;i<data.size();i++)
        {
            if(mp[data[i]]==1)
                res.push_back(data[i]);
        }
        *num1=res[0];
        *num2=res[1];

    }
};

和為S的連續(xù)正數(shù)序列

題目描述:小明很喜歡數(shù)學(xué),有一天他在做數(shù)學(xué)作業(yè)時(shí),要求計(jì)算出9~16的和,他馬上就寫出了正確答案是100。但是他并不滿足于此,他在想究竟有多少種連續(xù)的正數(shù)序列的和為100(至少包括兩個(gè)數(shù))勤哗。沒(méi)多久,他就得到另一組連續(xù)正數(shù)和為100的序列:18,19,20,21,22÷盏現(xiàn)在把問(wèn)題交給你,你能不能也很快的找出所有和為S的連續(xù)正數(shù)序列? Good Luck!

輸出描述:輸出所有和為S的連續(xù)正數(shù)序列。序列內(nèi)按照從小至大的順序芒划,序列間按照開(kāi)始數(shù)字從小到大的順序冬竟。

我的方法(不好)

class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int>> res;
        for(int i=1;i<sum;i++)
        {
            int nowsum=0;
            int j=i;
            while(nowsum<sum)
            {
                nowsum+=j;  //當(dāng)前連續(xù)的和
                j++;  //從當(dāng)前開(kāi)始往下加
            }
            if(nowsum==sum)
            {
                vector<int> sub;  //每次獲得到一個(gè)和為s的子串都要重新建一個(gè)數(shù)組
                for(int k=i;k<j;k++)
                    sub.push_back(k);
                res.push_back(sub);
            }
             
        }
        return res;
         
    }
};

雙指針:

class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int>> res;  //存放結(jié)果
        int phigh=2;  //兩個(gè)起點(diǎn),相當(dāng)于動(dòng)態(tài)窗口的兩邊民逼,根據(jù)其窗口內(nèi)的值的和來(lái)確定窗口的位置和大小
        int plow=1;
        while(phigh>plow)
        {
            int nowsum=(phigh+plow)*(phigh-plow+1)/2;  //由于是連續(xù)的诱咏,差為1的一個(gè)序列,那么求和公式是(a0+an)*n/2
            if(nowsum<sum)  //如果當(dāng)前窗口內(nèi)的值之和小于sum缴挖,那么右邊窗口右移一下
                phigh++;
            if(nowsum==sum)  //相等袋狞,那么就將窗口范圍的所有數(shù)添加進(jìn)結(jié)果集
            {
                vector<int> sub;
                for(int i=plow;i<=phigh;i++)
                    sub.push_back(i);
                res.push_back(sub);
                plow++;
            }
            if(nowsum>sum)  //如果當(dāng)前窗口內(nèi)的值之和大于sum,那么左邊窗口右移一下
                plow++;
        }
        return res;
    }
};

和為S的兩個(gè)數(shù)字(與上題相似)

題目描述:輸入一個(gè)遞增排序的數(shù)組和一個(gè)數(shù)字S映屋,在數(shù)組中查找兩個(gè)數(shù)苟鸯,使得他們的和正好是S,如果有多對(duì)數(shù)字的和等于S棚点,輸出兩個(gè)數(shù)的乘積最小的早处。

class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array,int sum) {
        vector<int> res;
        int plow=0;
        int phigh=array.size()-1;  //從末尾開(kāi)始
        while(phigh>plow)
        {
            if(array[phigh]+array[plow]<sum)
                plow++;
            if(array[phigh]+array[plow]>sum)
                phigh--;
            if(array[phigh]+array[plow]==sum)
            {
                res.push_back(array[plow]);
                res.push_back(array[phigh]);
                break;  //最外層的就是乘積最小的
            }
        }
        return res;
    }
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市瘫析,隨后出現(xiàn)的幾起案子砌梆,更是在濱河造成了極大的恐慌,老刑警劉巖贬循,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咸包,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡杖虾,警方通過(guò)查閱死者的電腦和手機(jī)烂瘫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)奇适,“玉大人坟比,你說(shuō)我怎么就攤上這事芦鳍。” “怎么了葛账?”我有些...
    開(kāi)封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵柠衅,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我籍琳,道長(zhǎng)茄茁,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任巩割,我火速辦了婚禮,結(jié)果婚禮上付燥,老公的妹妹穿的比我還像新娘宣谈。我一直安慰自己,他們只是感情好键科,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布闻丑。 她就那樣靜靜地躺著,像睡著了一般勋颖。 火紅的嫁衣襯著肌膚如雪嗦嗡。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天饭玲,我揣著相機(jī)與錄音侥祭,去河邊找鬼。 笑死茄厘,一個(gè)胖子當(dāng)著我的面吹牛矮冬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播次哈,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼胎署,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了窑滞?” 一聲冷哼從身側(cè)響起琼牧,我...
    開(kāi)封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎哀卫,沒(méi)想到半個(gè)月后巨坊,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡此改,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年抱究,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片带斑。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鼓寺,死狀恐怖勋拟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情妈候,我是刑警寧澤敢靡,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站苦银,受9級(jí)特大地震影響啸胧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜幔虏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一纺念、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧想括,春花似錦陷谱、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至铺根,卻和暖如春宪躯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背位迂。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工访雪, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掂林。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓冬阳,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親党饮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子肝陪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345