[剑指offer]刷题笔记


  • 两个链表的第一个公共结点

  • 数组中只出现一次的数字

  • 和为S的连续正序列

  • 和为S的两个数字(与上题类似)


两个链表的第一个公共结点

题目描述:输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)

我的方法(太笨了)

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;  //第一个链表和第二个链表的差值
        
        if(len1>=len2)  //第一个链表比第二个长 第一个链表先走差值
        {
            len=len1-len2;
            while(len>0)
            {
                p1=p1->next;
                len--;
            }
        }
        else  //第二个链表比第一个长 第二个链表先走完差值
        {
            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;
    }
};

长度相同有公共结点,第一次就遍历到;没有公共结点,走到尾部NULL相遇,返回NULL;长度不同有公共结点,第一遍差值就出来了,第二遍一起到公共结点;没有公共,一起到结尾NULL。

class Solution {
public:
   ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
       /*
        假定 List1长度: a+n  List2 长度:b+n, 且 a=b. 
        时间复杂度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;
     
}
        
};

数组中只出现一次的数字

题目描述:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

class Solution {
public:
    void FindNumsAppearOnce(vector data,int* num1,int *num2) {
        map mp;
        vector res;
        for(int i=0;i

和为S的连续正数序列

题目描述:小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

输出描述:输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序。

我的方法(不好)

class Solution {
public:
    vector > FindContinuousSequence(int sum) {
        vector> res;
        for(int i=1;i sub;  //每次获得到一个和为s的子串都要重新建一个数组
                for(int k=i;k

双指针:

class Solution {
public:
    vector > FindContinuousSequence(int sum) {
        vector> res;  //存放结果
        int phigh=2;  //两个起点,相当于动态窗口的两边,根据其窗口内的值的和来确定窗口的位置和大小
        int plow=1;
        while(phigh>plow)
        {
            int nowsum=(phigh+plow)*(phigh-plow+1)/2;  //由于是连续的,差为1的一个序列,那么求和公式是(a0+an)*n/2
            if(nowsum sub;
                for(int i=plow;i<=phigh;i++)
                    sub.push_back(i);
                res.push_back(sub);
                plow++;
            }
            if(nowsum>sum)  //如果当前窗口内的值之和大于sum,那么左边窗口右移一下
                plow++;
        }
        return res;
    }
};

和为S的两个数字(与上题相似)

题目描述:输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

class Solution {
public:
    vector FindNumbersWithSum(vector array,int sum) {
        vector res;
        int plow=0;
        int phigh=array.size()-1;  //从末尾开始
        while(phigh>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;
    }
};

你可能感兴趣的:([剑指offer]刷题笔记)