剑指offer——面试题18.1:删除链表中重复的节点

  1 // 面试题18(二):删除链表中重复的结点
  2 // 题目:在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重复
  3 // 结点被删除之后,链表如图3.4(b)所示。
  4
  5 #include <cstdio>
  6 #include "List.h"
  7
  8 void DeleteDuplication(ListNode** pHead)
  9 {
 10     if(pHead == nullptr || *pHead == nullptr)
 11         return;
 12
 13     ListNode* pPreNode = nullptr;
 14     ListNode* pNode = *pHead;
 15     while(pNode != nullptr)
 16     {
 17         ListNode *pNext = pNode->m_pNext;
 18         bool needDelete = false;
 19         if(pNext != nullptr && pNext->m_nValue == pNode->m_nValue)
 20             needDelete = true;
 21
 22         if(!needDelete)
 23         {
 24             pPreNode = pNode;
 25             pNode = pNode->m_pNext;
 26         }
 27         else
 28         {
 29             int value = pNode->m_nValue;
 30             ListNode* pToBeDel = pNode;
 31             while(pToBeDel != nullptr && pToBeDel->m_nValue == value)
 32             {
 33                 pNext = pToBeDel->m_pNext;
 34
 35                 delete pToBeDel;
 36                 pToBeDel = nullptr;
 37
 38                 pToBeDel = pNext;
 39             }
 40
 41             if(pPreNode == nullptr)
 42                 *pHead = pNext;
 43             else
 44                 pPreNode->m_pNext = pNext;
 45             pNode = pNext;
 46         }
 47     }
 48 }
 49
 50 // ====================测试代码====================
 51 void Test(char* testName, ListNode** pHead, int* expectedValues, int expectedLength)
 52 {
 53     if(testName != nullptr)
 54         printf("%s begins: ", testName);
 55
 56     DeleteDuplication(pHead);
 57
 58     int index = 0;
 59     ListNode* pNode = *pHead;
 60     while(pNode != nullptr && index < expectedLength)
 61     {
 62         if(pNode->m_nValue != expectedValues[index])
 63             break;
 64
 65         pNode = pNode->m_pNext;
 66         index++;
 67     }
 68
 69     if(pNode == nullptr && index == expectedLength)
 70         printf("Passed.\n");
 71     else
 72         printf("FAILED.\n");
 73 }
 74
 75 // 某些结点是重复的
 76 void Test1()
 77 {
 78     ListNode* pNode1 = CreateListNode(1);
 79     ListNode* pNode2 = CreateListNode(2);
 80     ListNode* pNode3 = CreateListNode(3);
 81     ListNode* pNode4 = CreateListNode(3);
 82     ListNode* pNode5 = CreateListNode(4);
 83     ListNode* pNode6 = CreateListNode(4);
 84     ListNode* pNode7 = CreateListNode(5);
 85
 86     ConnectListNodes(pNode1, pNode2);
 87     ConnectListNodes(pNode2, pNode3);
 88     ConnectListNodes(pNode3, pNode4);
 89     ConnectListNodes(pNode4, pNode5);
 90     ConnectListNodes(pNode5, pNode6);
 91     ConnectListNodes(pNode6, pNode7);
 92
 93     ListNode* pHead = pNode1;
 94
 95     int expectedValues[] = { 1, 2, 5 };
 96     Test("Test1", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
 97
 98     DestroyList(pHead);
 99 }
100
101 // 没有重复的结点
102 void Test2()
103 {
104     ListNode* pNode1 = CreateListNode(1);
105     ListNode* pNode2 = CreateListNode(2);
106     ListNode* pNode3 = CreateListNode(3);
107     ListNode* pNode4 = CreateListNode(4);
108     ListNode* pNode5 = CreateListNode(5);
109     ListNode* pNode6 = CreateListNode(6);
110     ListNode* pNode7 = CreateListNode(7);
111
112     ConnectListNodes(pNode1, pNode2);
113     ConnectListNodes(pNode2, pNode3);
114     ConnectListNodes(pNode3, pNode4);
115     ConnectListNodes(pNode4, pNode5);
116     ConnectListNodes(pNode5, pNode6);
117     ConnectListNodes(pNode6, pNode7);
118
119     ListNode* pHead = pNode1;
120
121     int expectedValues[] = { 1, 2, 3, 4, 5, 6, 7 };
122     Test("Test2", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
123
124     DestroyList(pHead);
125 }
126
127 // 除了一个结点之外其他所有结点的值都相同
128 void Test3()
129 {
130     ListNode* pNode1 = CreateListNode(1);
131     ListNode* pNode2 = CreateListNode(1);
132     ListNode* pNode3 = CreateListNode(1);
133     ListNode* pNode4 = CreateListNode(1);
134     ListNode* pNode5 = CreateListNode(1);
135     ListNode* pNode6 = CreateListNode(1);
136     ListNode* pNode7 = CreateListNode(2);
137
138     ConnectListNodes(pNode1, pNode2);
139     ConnectListNodes(pNode2, pNode3);
140     ConnectListNodes(pNode3, pNode4);
141     ConnectListNodes(pNode4, pNode5);
142     ConnectListNodes(pNode5, pNode6);
143     ConnectListNodes(pNode6, pNode7);
144
145     ListNode* pHead = pNode1;
146
147     int expectedValues[] = { 2 };
148     Test("Test3", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
149
150     DestroyList(pHead);
151 }
152
153 // 所有结点的值都相同
154 void Test4()
155 {
156     ListNode* pNode1 = CreateListNode(1);
157     ListNode* pNode2 = CreateListNode(1);
158     ListNode* pNode3 = CreateListNode(1);
159     ListNode* pNode4 = CreateListNode(1);
160     ListNode* pNode5 = CreateListNode(1);
161     ListNode* pNode6 = CreateListNode(1);
162     ListNode* pNode7 = CreateListNode(1);
163
164     ConnectListNodes(pNode1, pNode2);
165     ConnectListNodes(pNode2, pNode3);
166     ConnectListNodes(pNode3, pNode4);
167     ConnectListNodes(pNode4, pNode5);
168     ConnectListNodes(pNode5, pNode6);
169     ConnectListNodes(pNode6, pNode7);
170
171     ListNode* pHead = pNode1;
172
173     Test("Test4", &pHead, nullptr, 0);
174
175     DestroyList(pHead);
176 }
177
178 // 所有结点都成对出现
179 void Test5()
180 {
181     ListNode* pNode1 = CreateListNode(1);
182     ListNode* pNode2 = CreateListNode(1);
183     ListNode* pNode3 = CreateListNode(2);
184     ListNode* pNode4 = CreateListNode(2);
185     ListNode* pNode5 = CreateListNode(3);
186     ListNode* pNode6 = CreateListNode(3);
187     ListNode* pNode7 = CreateListNode(4);
188     ListNode* pNode8 = CreateListNode(4);
189
190     ConnectListNodes(pNode1, pNode2);
191     ConnectListNodes(pNode2, pNode3);
192     ConnectListNodes(pNode3, pNode4);
193     ConnectListNodes(pNode4, pNode5);
194     ConnectListNodes(pNode5, pNode6);
195     ConnectListNodes(pNode6, pNode7);
196     ConnectListNodes(pNode7, pNode8);
197
198     ListNode* pHead = pNode1;
199
200     Test("Test5", &pHead, nullptr, 0);
201
202     DestroyList(pHead);
203 }
204
205 // 除了两个结点之外其他结点都成对出现
206 void Test6()
207 {
208     ListNode* pNode1 = CreateListNode(1);
209     ListNode* pNode2 = CreateListNode(1);
210     ListNode* pNode3 = CreateListNode(2);
211     ListNode* pNode4 = CreateListNode(3);
212     ListNode* pNode5 = CreateListNode(3);
213     ListNode* pNode6 = CreateListNode(4);
214     ListNode* pNode7 = CreateListNode(5);
215     ListNode* pNode8 = CreateListNode(5);
216
217     ConnectListNodes(pNode1, pNode2);
218     ConnectListNodes(pNode2, pNode3);
219     ConnectListNodes(pNode3, pNode4);
220     ConnectListNodes(pNode4, pNode5);
221     ConnectListNodes(pNode5, pNode6);
222     ConnectListNodes(pNode6, pNode7);
223     ConnectListNodes(pNode7, pNode8);
224
225     ListNode* pHead = pNode1;
226
227     int expectedValues[] = { 2, 4 };
228     Test("Test6", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
229
230     DestroyList(pHead);
231 }
232
233 // 链表中只有两个不重复的结点
234 void Test7()
235 {
236     ListNode* pNode1 = CreateListNode(1);
237     ListNode* pNode2 = CreateListNode(2);
238
239     ConnectListNodes(pNode1, pNode2);
240
241     ListNode* pHead = pNode1;
242
243     int expectedValues[] = { 1, 2 };
244     Test("Test7", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
245
246     DestroyList(pHead);
247 }
248
249 // 结点中只有一个结点
250 void Test8()
251 {
252     ListNode* pNode1 = CreateListNode(1);
253
254     ConnectListNodes(pNode1, nullptr);
255
256     ListNode* pHead = pNode1;
257
258     int expectedValues[] = { 1 };
259     Test("Test8", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int));
260
261     DestroyList(pHead);
262 }
263
264 // 结点中只有两个重复的结点
265 void Test9()
266 {
267     ListNode* pNode1 = CreateListNode(1);
268     ListNode* pNode2 = CreateListNode(1);
269
270     ConnectListNodes(pNode1, pNode2);
271
272     ListNode* pHead = pNode1;
273
274     Test("Test9", &pHead, nullptr, 0);
275
276     DestroyList(pHead);
277 }
278
279 // 空链表
280 void Test10()
281 {
282     ListNode* pHead = nullptr;
283
284     Test("Test10", &pHead, nullptr, 0);
285 }
286
287 int main(int argc, char* argv[])
288 {
289     Test1();
290     Test2();
291     Test3();
292     Test4();
293     Test5();
294     Test6();
295     Test7();
296     Test8();
297     Test9();
298     Test10();
299
300     return 0;
301 }

原文地址:https://www.cnblogs.com/acm-jing/p/10409177.html

时间: 2024-10-10 07:22:59

剑指offer——面试题18.1:删除链表中重复的节点的相关文章

【剑指Offer面试题】二维数组中的查找

下决心AC所有剑指offer面试题. 九度OJ面试题地址:http://ac.jobdu.com/hhtproblems.php 书籍:何海涛--<剑指Offer:名企面试官精讲典型编程题> 对于面试题,面试官往往更希望我们能提出优化方法,这样更能体现我们的思维能力以及传说中的"内功".所以做剑指offer要着重训练这方面,多总结多细究,总是有好处的.加油~ 二维数组中的查找 时间限制:1 秒内存限制:32 兆 特殊判题:否提交:19005解决:3642 题目描述: 在一个

剑指Offer(链表)-删除链表中重复的节点

(删除链表中重复的节点)题目描述: 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 解题思路:这里的重复的节点不保留是将只要重复了的节点都要删除掉,所以考虑利用哈希set的方法,先进行重复性的判断,将重复的元素加入到哈希set中去,然后将重复的元素删除. 利用到了两个指针pre和cur,来表示前一个节点和当前节点. /* public

刷题--删除链表中重复的节点

题目描述: 在一个排序的链表中,存在重复的节点,请删除该链表中重复的节点,重复的节点不保留,返回链表头指针.例如,,链表1->2->3->3->4->4->5 处理后为 1->2->5 [解1]使用HashMap记录每个节点是否重复出现,时间复杂度为O(N),空间复杂度为O(N) 1 import java.util.*; 2 3 /* 4 public class ListNode { 5 int val; 6 ListNode next = null;

删除链表中重复的节点

因为这个程序快累死老子了,细节处理很麻烦package Solutions; import java.util.ArrayList; /** * Created by hu on 2015/12/12. *//** 删除链表中重复的结点*在一个排序的链表中,存在重复的结点,* 请删除该链表中重复的结点,重复的结点不保留,返回链表头指针.* 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5** */public class solut

剑指offer:删除链表中重复的节点

题目描述在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 # Definition for singly-linked list. class ListNode: def __init__(self, x): self.val = x self.next = None class Solution: def deleteDuplicat

【剑指Offer】删除链表中重复的节点

题目:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 A:当遍历到第一个值为重复的节点时,要有一个指针指向它的前一个节点    因为函数原型没有传二级指针进来,且头结点也有可能被删除,所以要构建一个新结点Head 用布尔型的flag_repeat判断是否有重复节点,若有重复节点则删除,若没有重复节点则移动指针 /* struct Li

[算法]删除链表中重复的节点

题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 代码 /* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } */ public class Solution { public List

58.删除链表中重复的节点

题目描述: ??在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 思路分析: ??两种思路: ??第一种方法不使用递归,设置一个指针让其指向链表的头结点,我们从头节点开始遍历,要删除重复节点就是判断当前节点的值是否和下一个节点值相等,如果是则往下遍历,直到遇到第一个不相等的节点,新的链表头就从该点开始,然后重复上面的操作找到下一个不重复

剑指offer 面试题(二维数组中的查找) (2)

面试题: 二维数组中的查找 /* 题目:   在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成 一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该数. */ ps:(其实前段时间我就做过这道题,今天看到了,觉得还是有点生,那就再来一次吧) 题目分析:  在分析这个问题的时候,我们首先要看,在一个二维数组中查找一个数字是否存在,那么很多人就觉得 简单了,遍历二维数组与所需要查找的数字进行比较不就完了!  不可否认的是你说的是可行的,可是