LeetCode-19
Posted zpchya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode-19相关的知识,希望对你有一定的参考价值。
2019/04/03
方法一:遍历两次链表,第一次遍历得到链表的长度,第二次遍历找到倒数第n个节点并删除它。
时间复杂度为O(6n),空间复杂度为O(1)
方法二:遍历一遍链表,遍历链表的同时将各节点地址放入容器中,遍历结束后通过容器下表删除倒数第n个节点。
时间复杂度为O(4n),空间复杂度为O(n)
ListNode* removeNthFromEnd(ListNode* head, int n) { vector<ListNode*> nodeVector; //创建一个节点容器 ListNode* pWorkNode = head; int i = 0; //链表长度 while (pWorkNode) //遍历链表 { nodeVector.push_back(pWorkNode); //将各个节点放入容器中 pWorkNode = pWorkNode->next; ++i; } int j = i + 1 - n; //待删除节点序号 if (1 == j) //如果删除的是第一个节点 { pWorkNode = head->next; delete head; head = pWorkNode; } else { nodeVector[j - 2]->next = nodeVector[j - 1]->next; delete nodeVector[j - 1]; } return head; }
这个算法实现非常差,时间复杂度并没有比遍历两边链表低多少,空间复杂度却变大很多。想的时候只记得降低遍历次数,没有更深的去想怎么降低遍历次数的同时使得空间复杂度仍是O(1)。
方法三:这个算法是看了别人才反应过来的,关键就在于怎么在依次遍历中确定这个节点顺序排在第几位。
时间复杂度为O(2n), 空间复杂度为O(1)
ListNode* removeNthFromEnd(ListNode* head, int n) { ListNode* pFirstNode = new ListNode(0); //为了统一删除节点的操作 pFirstNode->next = head; ListNode* pWorkNode1 = head; //确定待删除节点的顺序位置 ListNode* pWorkNode2 = pFirstNode; //遍历到待删除节点 while(n--) pWorkNode1 = pWorkNode1->next; while(pWorkNode1) //遍历到待删除节点的前一个节点 { pWorkNode1 = pWorkNode1->next; pWorkNode2 = pWorkNode2->next; } pWorkNode1 = pWorkNode2->next; pWorkNode2->next = pWorkNode1->next; delete pWorkNode1; return pFirstNode->next; }
总结:做题的时候就要多想,并不是说怎么把它实现了,而是怎么把它实现的更好,实现了有没有更好的方法,要多想!
以上是关于LeetCode-19的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode(19) - Remove Nth Node From End of List
LeetCode - 19 - 删除链表的倒数第N个节点 - Java