leetcode题目总结<2>

来源:互联网 发布:淘宝网官网电话 编辑:程序博客网 时间:2024/06/07 18:46

因为复习的缘故,一开始按tag做起,难度也是从简单到困难。


237. Delete Node in a Linked List

      这一题题目看了半天没看懂,实际上比较简单,就是给定一个List结点,从链表中删除他,代码如下:

<span style="font-size:18px;">//My code /** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    void deleteNode(ListNode* node) {        ListNode* nextnode = node->next;         node->val = nextnode->val;        node->next = nextnode->next;        delete(nextnode);    }};</span>

234. Palindrome Linked List

<span style="font-size:18px;">//My code//功能:判断一单向链表是否是回文链表(从前往后与从后往前读取内容一样),若是返回ture,否则返回false.//      要求时间复杂度为O(n),控件复杂度为O(1).ListNode* ReverseList(ListNode* head) //返回反转之后的头结点{ListNode* p1 = head;ListNode* p2 = head->next;ListNode* p3;while(p2){p3 = p2->next;p2->next = p1;p1 = p2;p2 = p3;}head->next = NULL;return p1;}bool isPalindrome(ListNode* head) {if(head == NULL || head->next == NULL)return true;ListNode* fast = head;ListNode* slow = head;ListNode* right;while(fast&&fast->next){fast = fast->next->next;slow = slow->next;}if(fast == NULL)   //链表节点数为偶数{//慢指针正好指向后面一部分,将后面一部分反转过来right = ReverseList(slow);}else              //链表节点数为奇数{//慢指针正好指向中间的结点,该节点无需反转right = ReverseList(slow->next);}while(head && right){if(head->val != right->val){return false;}head = head->next;right = right->next;}return true;}</span>


<span style="font-size:18px;">//others codeListNode* reverseList(ListNode* head) {ListNode* pre=NULL;ListNode* next=NULL;while(head!=NULL){next=head->next;head->next=pre;pre=head;head=next;}return pre;}bool isPalindrome(ListNode* head) {if(head==NULL||head->next==NULL)return true;ListNode* slow=head;ListNode* fast=head;while(fast->next!=NULL&&fast->next->next!=NULL){slow=slow->next;fast=fast->next->next;}slow->next=reverseList(slow->next);slow=slow->next;while(slow!=NULL){if(head->val!=slow->val)return false;head=head->next;slow=slow->next;}return true;}</span>
总结:此题思考了很长时间想不出能再O(n)的时间复杂度与O(1)的控件复杂度内解决的办法,最后参考网上的说明才知道了最常用的方法。首先是采用快慢指针遍历的方式迅速找到中点,这里快指针跑的节点数是慢指针的两倍,因此快指针到达链尾时慢指针正好在链中附近,这里说附近的原因就是因为链节点数的不同,若为偶数结点,快指针到链尾时,快指针正好在链中的下一个结点,若是奇数结点,快指针到链尾时慢指针正好在链中。因此我的代码中对这两种进行了分类处理。在找到链中元素后,将链中后面的元素反转,这样反转以后再跟头结点遍历一遍作比较就知道是否是回文链表了。这里看到别人的代码唯一的区别就是他没有对链表的奇偶数进行判别,这也是高明的地方。看while循环里面我的判断是fast&&fast->next;而他的代码里是fast->next&&fast->next->next。这回导致什么呢,这会导致在链表为偶数结点时,快指针到链尾后,慢指针还在中间靠前的那个结点上,这样用下面这两行代码就解决了链表是奇偶数判断的问题。
<span style="font-size:18px;">slow->next=reverseList(slow->next);slow=slow->next;</span>


203. Remove Linked List Elements

//My code //功能:删除单链表中的重复结点,可以有多个重复
/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* removeElements(ListNode* head, int val) {        ListNode* pre = NULL;        ListNode* cur = head;        ListNode* temp;        while(cur)        {            if(cur->val == val)            {                if(cur == head)    //是头结点                {                    head = cur->next;                    temp = cur;                    cur = cur->next;                    free(temp);                }                else                {                    temp = cur;                    cur = cur->next;                    pre->next = cur;                    free(temp);                }            }            else            {                pre = cur;                cur = cur->next;            }        }        return head;    }};
总结:这题是典型的删除链表指定值结点的题,如果说稍微有些不同的话,这题的链表里允许有重复结点。

160. Intersection of Two Linked Lists

//My code//功能:求两个链表的第一个公共结点
/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {    ListNode* pA = headA;ListNode* pB = headB;int lineA = 0, lineB = 0;while(pA){lineA++;pA = pA->next;}while(pB){lineB++;pB = pB->next;}if(lineA == 0 && lineB == 0)return NULL;pA = headA;pB = headB;if(lineA == lineB){while(pA && pB){if(pA->val == pB->val)return pA;pA = pA->next;pB = pB->next;}}else if(lineA > lineB){int space = lineA - lineB;while(space){pA = pA->next;space--;}while(pA && pB){if(pA->val == pB->val)return pA;pA = pA->next;pB = pB->next;}}else if(lineB > lineA){int space = lineB - lineA;while(space){pB = pB->next;space--;}while(pA && pB){if(pA->val == pB->val)return pA;pA = pA->next;pB = pB->next;}}return NULL;    }};

//others codeListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {    ListNode *p1 = headA;    ListNode *p2 = headB;            if (p1 == NULL || p2 == NULL) return NULL;    while (p1 != NULL && p2 != NULL && p1 != p2) {        p1 = p1->next;        p2 = p2->next;        if (p1 == p2) return p1;        if (p1 == NULL) p1 = headB;        if (p2 == NULL) p2 = headA;    }            return p1;}
总结:这道题一开始也没想到什么好的解决办法,后来参考网上的资料知道了大致的思路,先遍历一遍统计两个链表的长度,若同样长的话一起遍历下去找到首个相同的结点,若不一样长,长的那个链表先遍历两链表长度之差个结点后,两链表编程一样长在一起遍历找交叉结点。

141. Linked List Cycle

//My code//功能:检测一个链表是否是循环链表/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    bool hasCycle(ListNode *head) {        if(head == NULL || head->next == NULL)             return false;                     ListNode* fastNode = head;        ListNode* slowNode = head;                while(fastNode->next && fastNode->next->next)        {            fastNode = fastNode->next->next;            slowNode = slowNode->next;                        if(fastNode == slowNode)                return true;        }        return false;    }};
总结:这一题是很简单的,算法的思路也很明确,判断链表是否是循环链表比较快速的方式那就是快慢指针了,算出来的结果与别人的也相差无几。就是不要忘记最开始的判断情况。

83. Remove Duplicates from Sorted List

//My code//功能:从已排好序的链表中删除重复的结点/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* deleteDuplicates(ListNode* head) {        if(head == NULL || head->next == NULL)            return head;        ListNode* p1 = head;        ListNode* p2 = head->next;        ListNode* temp;        while(p2)        {            if(p1->val == p2->val)            {                temp = p2;                p2 = p2->next;                p1->next = p2;                free(temp);            }            else            {                p1 = p2;                p2 = p2->next;            }        }        return head;    }};
总结:类似于删除单链表结点的扩展,还是比较简单的。

24. Swap Nodes in Pairs

//迭代法/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* swapPairs(ListNode* head) {        ListNode* dummy=new ListNode(0);        dummy->next=head;        ListNode* prev=dummy;        while(head &&head->next)        {            ListNode* nn=head->next->next;            prev->next=head->next;            head->next->next=head;            head->next=nn;            prev=head;            head=nn;                   }        return dummy->next;            }};
//迭代法ListNode* swapPairs1(ListNode* head) {    if (!head || !(head->next))        return head;    ListNode *res = head->next;    head->next = swapPairs(res->next);    res->next = head;    return res;}

总结:这道题没做出来,似乎很不喜欢做这类题目,参考的别人的两种方法,下面来分析分析:

迭代法中,插入了一个头结点,并将prev指针指向他,在每次迭代中,始终保持prev在head的后面,然后head前进两格,再做处理。可参考下面的示意图。

ListNode* nn=head->next->next;①prev->next=head->next;②head->next->next=head;③head->next=nn;④prev=head;⑤head=nn;⑥

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 打卡指纹不清晰怎么办 驾考指纹录不上怎么办 指纹读不出来怎么办 中国银行卡吞了怎么办 存钱钱卡住了怎么办 办理身份证指纹录不上怎么办 手指没有指纹了怎么办 签了户口身份证怎么办 生了三胎户口怎么办 双户口注销学历怎么办 户口注销了社保怎么办 科一指纹录不上怎么办 右倒库右边太宽怎么办 手机录不了指纹怎么办 6sp指纹不灵敏怎么办 手指纹汗多怎么办? 手指没指纹怎么办身份证 青岛身份证丢了怎么办 新身份证没激活怎么办 坐轻轨没身份证怎么办 办身份证指纹录不上怎么办 指纹固化剂干了怎么办 指纹解锁没反应怎么办 荣耀v8指纹失灵怎么办 指纹多次不匹配怎么办 华为指纹被禁用怎么办 手脱皮没有指纹怎么办 手脱皮手机指纹怎么办 手脱皮录指纹怎么办 科二指纹打不上怎么办 三星手机无法解锁怎么办 iphone7指纹坏了怎么办 苹果8录不上指纹怎么办 手机套总是粘指纹怎么办 华为p9指纹禁用怎么办 华为p10升级失败怎么办 手机指纹锁没反应怎么办 华为手机指纹禁用怎么办 excel输入值非法怎么办 excel表数字乱码怎么办 excel表格打不开了怎么办