면접 에서 흔히 볼 수 있 는 링크 문제

본 고 는 아래 의 블 로그 에서 옮 겨 창작 물 을 존중 하고 정리 해 주 셔 서 감사합니다.https://blog.csdn.net/luckyxiaoqiang/article/details/7393134
링크 는 가장 기본 적 인 데이터 구조 로 면접 관 들 도 링크 로 면접 자의 기본 능력 을 고찰 하고 링크 와 관련 된 조작 이 상대 적 으로 간단 하 며 코드 작성 능력 도 고찰 하기에 적합 하 다.링크 의 조작 도 지침 을 떠 날 수 없고 지침 은 실 수 를 하기 쉽다.여러 가지 원인 을 종합 하면 링크 문 제 는 면접 에서 매우 중요 한 위 치 를 차지한다.본 고 는 링크 와 관련 된 면접 문 제 를 전면적으로 정리 하여 일자 리 를 찾 는 학생 들 에 게 도움 이 되 기 를 바 랍 니 다.
링크 노드 설명 은 다음 과 같 습 니 다.
struct ListNode {     int m_nKey;     ListNode * m_pNext;
};
제목 목록:
1. 단일 체인 테이블 의 결점 의 개 수 를 구하 십시오. 2. 단일 체인 테이블 을 반전 시 킵 니 다. 3. 단일 체인 테이블 의 마지막 K 개의 결점 찾기 (k > 0) 4. 단일 체인 테이블 의 중간 결점 찾기 5. 끝 에서 끝까지 단일 체인 테이블 인쇄 6. 이미 알 고 있 는 두 개의 단일 체인 표 pHead 1 과 pHead 2 는 각각 질서 가 있 고 이 를 하나의 체인 표 로 합 쳐 도 질서 가 있 습 니 다. 7. 하나의 단일 체인 표 에 고리 가 있 는 지 판단 합 니 다. 8. 두 개의 단일 체인 표 가 교차 하 는 지 판단 합 니 다. 9. 두 개의 단일 체인 표 가 교차 하 는 첫 번 째 노드 10. 이미 알 고 있 는 하나의 단일 체인 표 에 고리 가 존재 합 니 다.링 에 들 어 가 는 첫 번 째 노드 11. 단일 체인 헤더 포인터 pHead 와 한 노드 포인터 pToBeDeleted, O (1) 시간 복잡 도 삭제 노드 pToBeDeleted
상세 한 해답
1. 단일 체인 표 의 결산 점 의 개 수 를 구하 다.
이것 은 가장 기본 적 인 것 입 니 다. 정확 한 코드 를 신속하게 쓸 수 있 고 링크 가 비어 있 는 지 확인 할 수 있 습 니 다.시간 복잡 도 는 O (n) 이다.참조 코드 는 다음 과 같 습 니 다.

   
   
   
   
  1. //
  2. unsigned int GetListLength(ListNode * pHead)
  3. {
  4. if(pHead == NULL)
  5. return 0;
  6. unsigned int nLength = 0;
  7. ListNode * pCurrent = pHead;
  8. while(pCurrent != NULL)
  9. {
  10. nLength++;
  11. pCurrent = pCurrent->m_pNext;
  12. }
  13. return nLength;
  14. }


2.

, , 。 。 O(n)。 :


   
   
   
   
  1. //
  2. ListNode * ReverseList(ListNode * pHead)
  3. {
  4. // , ,
  5. if(pHead == NULL || pHead->m_pNext == NULL)
  6. return pHead;
  7. ListNode * pReversedHead = NULL; // , NULL
  8. ListNode * pCurrent = pHead;
  9. while(pCurrent != NULL)
  10. {
  11. ListNode * pTemp = pCurrent;
  12. pCurrent = pCurrent->m_pNext;
  13. pTemp->m_pNext = pReversedHead; // ,
  14. pReversedHead = pTemp;
  15. }
  16. return pReversedHead;
  17. }

3. K (k > 0)

, , (n-k) 。 ,k 0,k 1,k 。 O(n)。 。

, 。

, k , k-1, , , k 。


   
   
   
   
  1. // K
  2. ListNode * RGetKthNode(ListNode * pHead, unsigned int k) // R
  3. {
  4. if(k == 0 || pHead == NULL) // k 1 , k 0 NULL
  5. return NULL;
  6. ListNode * pAhead = pHead;
  7. ListNode * pBehind = pHead;
  8. while(k > 1 && pAhead != NULL) // k
  9. {
  10. pAhead = pAhead->m_pNext;
  11. k--;
  12. }
  13. if(k > 1 || pAhead == NULL) // k, NULL
  14. return NULL;
  15. while(pAhead->m_pNext != NULL) // ,
  16. {
  17. pBehind = pBehind->m_pNext;
  18. pAhead = pAhead->m_pNext;
  19. }
  20. return pBehind; // k
  21. }

4.

。 , , , , , , , (n/2+1) 。 , 1 2 。 O(n)。 :


   
   
   
   
  1. // , n(n>0), n/2+1
  2. ListNode * GetMiddleNode(ListNode * pHead)
  3. {
  4. if(pHead == NULL || pHead->m_pNext == NULL) // ,
  5. return pHead;
  6. ListNode * pAhead = pHead;
  7. ListNode * pBehind = pHead;
  8. while(pAhead->m_pNext != NULL) // , ,
  9. {
  10. pAhead = pAhead->m_pNext;
  11. pBehind = pBehind->m_pNext;
  12. if(pAhead->m_pNext != NULL)
  13. pAhead = pAhead->m_pNext;
  14. }
  15. return pBehind; //
  16. }


5.

, , 。 , , , 。 。 O(n)。 :


   
   
   
   
  1. // ,
  2. void RPrintList(ListNode * pHead)
  3. {
  4. std:: stack s;
  5. ListNode * pNode = pHead;
  6. while(pNode != NULL)
  7. {
  8. s.push(pNode);
  9. pNode = pNode->m_pNext;
  10. }
  11. while(!s.empty())
  12. {
  13. pNode = s.top();
  14. printf( "%d\t", pNode->m_nKey);
  15. s.pop();
  16. }
  17. }


   
   
   
   
  1. // ,
  2. void RPrintList(ListNode * pHead)
  3. {
  4. if(pHead == NULL)
  5. {
  6. return;
  7. }
  8. else
  9. {
  10. RPrintList(pHead->m_pNext);
  11. printf( "%d\t", pHead->m_nKey);
  12. }
  13. }


6.  pHead1 pHead2 ,

。 , 。 O(1) 。 O(max(len1, len2))。 :


   
   
   
   
  1. //
  2. ListNode * MergeSortedList(ListNode * pHead1, ListNode * pHead2)
  3. {
  4. if(pHead1 == NULL)
  5. return pHead2;
  6. if(pHead2 == NULL)
  7. return pHead1;
  8. ListNode * pHeadMerged = NULL;
  9. if(pHead1->m_nKey < pHead2->m_nKey)
  10. {
  11. pHeadMerged = pHead1;
  12. pHeadMerged->m_pNext = NULL;
  13. pHead1 = pHead1->m_pNext;
  14. }
  15. else
  16. {
  17. pHeadMerged = pHead2;
  18. pHeadMerged->m_pNext = NULL;
  19. pHead2 = pHead2->m_pNext;
  20. }
  21. ListNode * pTemp = pHeadMerged;
  22. while(pHead1 != NULL && pHead2 != NULL)
  23. {
  24. if(pHead1->m_nKey < pHead2->m_nKey)
  25. {
  26. pTemp->m_pNext = pHead1;
  27. pHead1 = pHead1->m_pNext;
  28. pTemp = pTemp->m_pNext;
  29. pTemp->m_pNext = NULL;
  30. }
  31. else
  32. {
  33. pTemp->m_pNext = pHead2;
  34. pHead2 = pHead2->m_pNext;
  35. pTemp = pTemp->m_pNext;
  36. pTemp->m_pNext = NULL;
  37. }
  38. }
  39. if(pHead1 != NULL)
  40. pTemp->m_pNext = pHead1;
  41. else if(pHead2 != NULL)
  42. pTemp->m_pNext = pHead2;
  43. return pHeadMerged;
  44. }


   
   
   
   
  1. ListNode * MergeSortedList(ListNode * pHead1, ListNode * pHead2)
  2. {
  3. if(pHead1 == NULL)
  4. return pHead2;
  5. if(pHead2 == NULL)
  6. return pHead1;
  7. ListNode * pHeadMerged = NULL;
  8. if(pHead1->m_nKey < pHead2->m_nKey)
  9. {
  10. pHeadMerged = pHead1;
  11. pHeadMerged->m_pNext = MergeSortedList(pHead1->m_pNext, pHead2);
  12. }
  13. else
  14. {
  15. pHeadMerged = pHead2;
  16. pHeadMerged->m_pNext = MergeSortedList(pHead1, pHead2->m_pNext);
  17. }
  18. return pHeadMerged;
  19. }


7.

。 , , 。 , , , , , 。 O(n)。 :


   
   
   
   
  1. bool HasCircle(ListNode * pHead)
  2. {
  3. ListNode * pFast = pHead; //
  4. ListNode * pSlow = pHead; //
  5. while(pFast != NULL && pFast->m_pNext != NULL)
  6. {
  7. pFast = pFast->m_pNext->m_pNext;
  8. pSlow = pSlow->m_pNext;
  9. if(pSlow == pFast) // ,
  10. return true;
  11. }
  12. return false;
  13. }


8.

, 。 , , 。 , , , , , , 。 O(len1+len2), , O(1)。 :


   
   
   
   
  1. bool IsIntersected(ListNode * pHead1, ListNode * pHead2)
  2. {
  3. if(pHead1 == NULL || pHead2 == NULL)
  4. return false;
  5. ListNode * pTail1 = pHead1;
  6. while(pTail1->m_pNext != NULL)
  7. pTail1 = pTail1->m_pNext;
  8. ListNode * pTail2 = pHead2;
  9. while(pTail2->m_pNext != NULL)
  10. pTail2 = pTail2->m_pNext;
  11. return pTail1 == pTail2;
  12. }

9.
, len1, 。
, len2, , , , 。
, len1 len2, len1-len2 , , , 。

,O(len1+len2)。 :


   
   
   
   
  1. ListNode* GetFirstCommonNode(ListNode * pHead1, ListNode * pHead2)
  2. {
  3. if(pHead1 == NULL || pHead2 == NULL)
  4. return NULL;
  5. int len1 = 1;
  6. ListNode * pTail1 = pHead1;
  7. while(pTail1->m_pNext != NULL)
  8. {
  9. pTail1 = pTail1->m_pNext;
  10. len1++;
  11. }
  12. int len2 = 1;
  13. ListNode * pTail2 = pHead2;
  14. while(pTail2->m_pNext != NULL)
  15. {
  16. pTail2 = pTail2->m_pNext;
  17. len2++;
  18. }
  19. if(pTail1 != pTail2) // NULL
  20. return NULL;
  21. ListNode * pNode1 = pHead1;
  22. ListNode * pNode2 = pHead2;
  23. // ,
  24. if(len1 > len2)
  25. {
  26. int k = len1 - len2;
  27. while(k--)
  28. pNode1 = pNode1->m_pNext;
  29. }
  30. else
  31. {
  32. int k = len2 - len1;
  33. while(k--)
  34. pNode2 = pNode2->m_pNext;
  35. }
  36. while(pNode1 != pNode2)
  37. {
  38. pNode1 = pNode1->m_pNext;
  39. pNode2 = pNode2->m_pNext;
  40. }
  41. return pNode1;
  42. }

10. ,

, 。 ( ), , 。 :


   
   
   
   
  1. ListNode* GetFirstNodeInCircle(ListNode * pHead)
  2. {
  3. if(pHead == NULL || pHead->m_pNext == NULL)
  4. return NULL;
  5. ListNode * pFast = pHead;
  6. ListNode * pSlow = pHead;
  7. while(pFast != NULL && pFast->m_pNext != NULL)
  8. {
  9. pSlow = pSlow->m_pNext;
  10. pFast = pFast->m_pNext->m_pNext;
  11. if(pSlow == pFast)
  12. break;
  13. }
  14. if(pFast == NULL || pFast->m_pNext == NULL)
  15. return NULL;
  16. // ,
  17. ListNode * pAssumedTail = pSlow;
  18. ListNode * pHead1 = pHead;
  19. ListNode * pHead2 = pAssumedTail->m_pNext;
  20. ListNode * pNode1, * pNode2;
  21. int len1 = 1;
  22. ListNode * pNode1 = pHead1;
  23. while(pNode1 != pAssumedTail)
  24. {
  25. pNode1 = pNode1->m_pNext;
  26. len1++;
  27. }
  28. int len2 = 1;
  29. ListNode * pNode2 = pHead2;
  30. while(pNode2 != pAssumedTail)
  31. {
  32. pNode2 = pNode2->m_pNext;
  33. len2++;
  34. }
  35. pNode1 = pHead1;
  36. pNode2 = pHead2;
  37. // ,
  38. if(len1 > len2)
  39. {
  40. int k = len1 - len2;
  41. while(k--)
  42. pNode1 = pNode1->m_pNext;
  43. }
  44. else
  45. {
  46. int k = len2 - len1;
  47. while(k--)
  48. pNode2 = pNode2->m_pNext;
  49. }
  50. while(pNode1 != pNode2)
  51. {
  52. pNode1 = pNode1->m_pNext;
  53. pNode2 = pNode2->m_pNext;
  54. }
  55. return pNode1;
  56. }


11. pHead pToBeDeleted,O(1) pToBeDeleted

 
   
  

, , , O(n)。 , , , 。 , , , O(1)。 :


   
   
   
   
  1. void Delete(ListNode * pHead, ListNode * pToBeDeleted)
  2. {
  3. if(pToBeDeleted == NULL)
  4. return;
  5. if(pToBeDeleted->m_pNext != NULL)
  6. {
  7. pToBeDeleted->m_nKey = pToBeDeleted->m_pNext->m_nKey; // ,
  8. ListNode * temp = pToBeDeleted->m_pNext;
  9. pToBeDeleted->m_pNext = pToBeDeleted->m_pNext->m_pNext;
  10. delete temp;
  11. }
  12. else //
  13. {
  14. if(pHead == pToBeDeleted) //
  15. {
  16. pHead = NULL;
  17. delete pToBeDeleted;
  18. }
  19. else
  20. {
  21. ListNode * pNode = pHead;
  22. while(pNode->m_pNext != pToBeDeleted) //
  23. pNode = pNode->m_pNext;
  24. pNode->m_pNext = NULL;
  25. delete pToBeDeleted;
  26. }
  27. }
  28. }



좋은 웹페이지 즐겨찾기