python 单链表是否有回路_第5章 第1节 链表
● 請你說出幾種基本的數據結構,
參考回答:
常見的基本的數據結構有鏈表、棧、隊列、樹(只列出面試常考的基本數據結構)
1、鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列節點組成,這些節點不必在內存中相連。每個節點由數據部分Data和鏈部分Next,Next指向下一個節點,這樣當添加或者刪除時,只需要改變相關節點的Next的指向,效率很高。
棧和隊列是比較特殊的線性表
棧是限制插入和刪除只能在一個位置上進行的表,后進先出
隊列只允許在front端進行刪除操作,在rear端進行插入操作,
樹:樹型結構是一類非常重要的非線性數據結構,考察主要以二叉樹為主,
● 手寫代碼:怎么判斷鏈表有環,怎么找環節點
參考回答:
判斷是否有環以及環節點
public?class?Solution?{ListNode?EntryNodeOfLoop(ListNode?h){if(h?==?null?||?h.next?==?null)return?null;ListNode?slow?=?h;ListNode?fast?=?h;while(fast?!=?null?&&?fast.next?!=?null?){slow?=?slow.next;fast?=?fast.next.next;if(slow?==?fast){ListNode?p=h;
ListNode q=slow;//相當于讓q指向了m1
復制代碼1
2
3
4
5
6
7
8
9
10while(p != q){
p = p.next;
q = q.next;
}
if(p == q)
return?q;
}
}
return?null;
}
● 手寫代碼:一個單向鏈表,給出頭結點,找出倒數第N個結點,要求O(N)的時間復雜度;
參考回答:
JAVA版本:
public?class?Solution?{public?ListNode?FindNthToTail(ListNode?head,int?N)?{ListNode?pre=null,p=null;
//兩個指針都指向頭結點
p=head;
pre=head;
//記錄N值
int a=N;
//記錄節點的個數
int count=0;
//p指針先跑,并且記錄節點數,當p指針跑了N-1個節點后,pre指針開始跑,
//當p指針跑到最后時,pre所指指針就是倒數第N個節點
while(p!=null){p=p.next;count++;if(N<1){pre=pre.next;}N--;}
//如果節點個數小于所求的倒數第N個節點,則返回空
if(count
C/C++版本:
復制代碼1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32class?Solution {
public:
ListNode* FindNthToTail(ListNode* pListHead, unsignedint?N) {
if(pListHead==NULL||N==0)
return?NULL;
ListNode*pTail=pListHead,*pHead=pListHead;
for(int?i=1;i
{
if(pHead->next!=NULL)
pHead=pHead->next;
else
return?NULL;
}
while(pHead->next!=NULL)
{
pHead=pHead->next;
pTail=pTail->next;
}
return?pTail;
}
};
Python:
class?Solution:
def FindNthToTail(self, head, N):
# write code here
res=[]
while?head:
res.append(head)
head=head.next
if?N>len(res) or N<1:
return
return?res[-N]
● 請問如何判斷一個單向鏈表存在回路?
參考回答:
方法1:用一個指針數組A,存儲已訪問過的節點。用一個指針p,每次在鏈表上移動一步,然后與指針數組A比較,若數組中沒有指針與p相同,說明第一次訪問p,將p放入數組中;若有指針與p相同,則存在環路,且第一次相同的節點就是環的入口點。
鏈表長度為n,則需要空間o(n),且每次要與指針數組比較,時間復雜度為 O(n^2)。
方法2:在節點上記錄該節點是否被訪問過,如果在指針移動過程中遇到已訪問過的節點,說明存在環路。同樣地,第一次相同的節點就是環的入口點。
方法3:用兩個指針,pSlow,pFast,一個慢一個快,慢的一次跳一步,,快的一次跳兩步,如果快的能追上慢的就表示有環(pSlow == pFast )。
● 請問如何判斷一個鏈表是否有環
參考回答:
方法1:用一個指針數組A,存儲已訪問過的節點。用一個指針p,每次在鏈表上移動一步,然后與指針數組A比較,若數組中沒有指針與p相同,說明第一次訪問p,將p放入數組中;若有指針與p相同,則存在環路,且第一次相同的節點就是環的入口點。
鏈表長度為n,則需要空間o(n),且每次要與指針數組比較,時間復雜度為 O(n^2)。
方法2:在節點上記錄該節點是否被訪問過,如果在指針移動過程中遇到已訪問過的節點,說明存在環路。同樣地,第一次相同的節點就是環的入口點。
方法3:用兩個指針,pSlow,pFast,一個慢一個快,慢的一次跳一步,,快的一次跳兩步,如果快的能追上慢的就表示有環(pSlow == pFast )。
● 請問如何判斷兩個鏈表是否相交
參考回答:
從頭遍歷兩個鏈表。創建兩個棧,第一個棧存儲第一個鏈表的節點,第二個棧存儲第二個鏈表的節點。每遍歷到一個節點時,就將該節點入棧。兩個鏈表都入棧結束后。則通過top判斷棧頂的節點是否相等即可判斷兩個單鏈表是否相交。因為我們知道,若兩個鏈表相交,則從第一個相交節點開始,后面的節點都相交。若兩鏈表相交,則循環出棧,直到遇到兩個出棧的節點不相同,則這個節點的后一個節點就是第一個相交的節點。
node temp=NULL; //存第一個相交節點
while(!stack1.empty()&&!stack1.empty()) //兩棧不為空
復制代碼1
2
3
4
5
6
7
8
9{
temp=stack1.top();
stack1.pop();
stack2.pop();
if(stack1.top()!=stack2.top())
{
break;
}
}
● 手寫代碼:循環鏈表插入元素
參考回答:
typedef?struct?_tag_CircleListNode{struct?_tag_CircleListNode?*?next;}CircleListNode;typedef?struct?_tag_CircleList{CircleListNode?header;CircleListNode*?slider;int?length;}TCircleList;
//插入元素
int?CircleList_insert(CircleList*?list,?CireListNode*?node,?int?pos){int?ret?=?0,?i=0;TCircleList*?sList?=?(TCircleList*)list;if?(list?==?NULL?||?node==?NULL?||?pos<0){return?-1;}CircleListNode*?current?=?(CircleListNode*)sList;for(i=0;?(inext?!=?NULL);?i++){current?=?current->next;}
//current->next 0號節點的地址
復制代碼1
2node->next = current->next; //1
current->next = node; //2
//若第一次插入節點
if(?sList->length?==?0?){sList->slider?=?node;}sList->length++;
//若頭插法 current仍然指向頭部
//(原因是:跳0步,沒有跳走) 中間第一種情況
復制代碼1
2if( current == (CircleListNode*)sList )
{
//獲取最后一個元素
復制代碼1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24CircleListNode* last = CircleList_Get(sList, sList->length - 1);
last->next = current->next;//3
}
return?ret;
}
CircleListNode* CircleList_Get(CircleList* list,int?pos)// O(n)
{
TCircleList* sList = (TCircleList*)list;
CircleListNode* ret = NULL;
int?i = 0;
if?(list==NULL || pos<0)
{
return?NULL;
}
{
CircleListNode* current = (CircleListNode*)sList;
for(i=0; i
{
current = current->next;
}
ret = current->next;
}
return?ret;
}
總結
以上是生活随笔為你收集整理的python 单链表是否有回路_第5章 第1节 链表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: unzip 解压_每天一条Linux命令
- 下一篇: websocket python爬虫_p