17_7_13:合併兩個有序鏈表。實現1+2+3+...+n,不使用常規方法

1.【基礎題】–合併兩個有序鏈表,合併以後的鏈表依舊有序。
2.【附加題】–實現1+2+3…+n,要求不能使用乘除法、循環、條件判斷、選擇相關的關鍵字。(這個題有多種解法,大家可以儘量去思考,這個題最優的解法時間複雜度是O(1),大家可以去嘗試實現)

1,基礎題:

#include <stdio.h>

typedef struct ListNode
{
    int _val;
    struct ListNode* _pNext;
}Node, *PNode;

//默認是從小到大排序
PNode MergeOrderList(PNode pNode_1, PNode pNode_2)
{
    PNode pNew = NULL; //作爲返回值
    PNode pCur = NULL; //作爲遍歷中的指針


    if (pNode_1 == NULL && pNode_2 == NULL) //兩者都爲空的情況
        return NULL;
    else if (pNode_1 == NULL)  //pNode_1爲空,pNode_2不爲空
        return pNode_2;
    else if (pNode_2 == NULL)  //pNode_2爲空,pNode_1不爲空
        return pNode_1;

    //給pCur賦初值,指向值最小的節點
    //此時,pNode_1與pNode_2不爲空
    pCur = (Node* )malloc(sizeof(Node));
    if (pNode_1->_val < pNode_2->_val)
    {
        pCur->_val = pNode_1->_val;
        pNode_1 = pNode_1->_pNext;
    }
    else
    {
        pCur->_val = pNode_2->_val;
        pNode_2 = pNode_2->_pNext;
    }

    pCur->_pNext = NULL;
    pNew = pCur;

    //通過兩個指針一直循環比較
    while (pNode_1 && pNode_2)
    {
        PNode pTemp = (PNode *)malloc(sizeof(PNode));

        if (pNode_1->_val < pNode_2->_val)
        {
            pTemp->_val = pNode_1->_val;
            pCur->_pNext = pTemp;
            pNode_1 = pNode_1->_pNext;
        }
        else
        {
            pTemp->_val = pNode_2->_val;
            pCur->_pNext = pTemp;
            pNode_2 = pNode_2->_pNext;
        }

        pTemp->_pNext = NULL;
        pCur = pCur->_pNext;
    }

    //比較還有鏈表有剩餘元素沒有比較的情況
    if (pNode_1)
        pCur->_pNext = pNode_1;
    else
        pCur->_pNext = pNode_2;

    return pNew;
}

//打印鏈表函數
void PrintList(PNode pHead)
{
    while (pHead)
    {
        printf("%d->", pHead->_val);
        pHead = pHead->_pNext;
    }
    printf("NULL\n");
}

//銷燬鏈表
void Destroy(PNode pHead)
{
    PNode pTemp = pHead;
    while (pHead)
    {
        pTemp = pHead;
        pHead = pHead->_pNext;
        free(pTemp);
        pTemp = NULL:
    }
}

2,附加題
既然不能使用常規手段,那麼就需要利用一些語法特性了。
思前想後,本人,只想出來了兩種方法。

a,
本來我是使用遞歸實現的

size_t Add1ToN(size_t n)
{
    if (0 == n)
        return 0;

    return n+Add1ToN(n-1);
}

但是後來發現,有一個if判斷,如何去掉這個判斷n爲0的特殊if語句呢。突然想到利用邏輯與&&的短路性質,第一個條件爲假時,不再判斷第二個條件。可以修改如下:

size_t Add1ToN(size_t n, size_t* sum)
{
    n && Add1ToN(n-1, &sum);
    *sum += n;

    return sum;
}

b,第二種方法,我想既然是O(1)的時間複雜度。那麼恐怕沒有隻有查表法了(下面當n從0到19時,表內事先存儲的值)

size_t tables[20] = {0,1,3,6,10,15,21,28,36,45,
55,66,78,91,105,120,136,163,171,190};

雖然查表法的時間複雜度是O(1),但是使用空間換時間的做法。

當然,還有許多中方法去實現累計結果,推薦博文:http://blog.csdn.net/cxllyg/article/details/7583646

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章