按照以往的习惯,这种题我们需要遍历整个链表,找到需要删除节点的前一个节点,这样我们就可以操作删除的方法了,这种方法需要O(n)的时间复杂度,但这里要求我们在O(1)的时间下完成。我们只能想其他的方法。
算法思想:其实我们也不需要知道删除节点前一个节点。我们的做法是将删除节点的后边一个节点的值赋给要删除的节点(即把要删除节点的值覆盖),然后将删除节点后边的节点删除(delete)即可。其中我们还需要检查要删除节点的位置,具体问题具体分析,要做到全面。
算法实现:
1 typedef struct ListNode{ 2 int data; 3 struct ListNode *next; 4 }ListNode; 5 6 void deleteNode(ListNode **pHead, ListNode *valueIndex){ 7 if(!pHead || !valueIndex){ //输入失败 8 return; 9 } 10 11 if(valueIndex->next != NULL){ //情况1,如果节点不是尾节点,我们将需要删除节点的后边的节点指赋给此节点。然后删除他后边的节点 12 ListNode *node = valueIndex->next; 13 valueIndex->data = node->data; 14 valueIndex->next = node->next; 15 16 delete node; 17 node = NULL; 18 } 19 else if(*pHead == valueIndex){ //如果只有一个节点 20 delete valueIndex; 21 *pHead = NULL; 22 valueIndex = NULL; 23 } 24 else{ //如果删除为节点,则遍历全部节点 25 ListNode *p = *pHead; 26 while( p->next != valueIndex){ 27 p = p->next; 28 } 29 30 p->next = NULL; 31 delete valueIndex; 32 valueINdex = NULL; 33 } 34 }
参考资料:
《剑指offer》