ソードフィンガーオファー質問22-リンクリストの下からK番目のノード

ソードフィンガーオファー質問22-リンクリストの下からK番目のノード

トピック

リンクリストを入力し、リンクリストの下からK番目のノードを出力します。ほとんどの人の習慣に合わせるために、この質問の最初から数え始めます。つまり、リンクリストの終了ノードは下から最初のノードです。たとえば、リンクリストには6つのノードがあります。ヘッドノードから始めて、それらの値は1、2、3、4、5、6です。リンクリストの下から3番目のノードは、値が4のノードです。 。ノードは次のように定義されます。

struct ListNode
{
    
    
	int m_nValue;
	ListNode* m_pNext;
}

考え

下からk番目のノードを取得するための最も自然なアイデアは、もちろん最初に最後に移動してから、Kステップに戻ることです。しかし、定義からわかるように、これは単一リンクリストです。したがって、これは機能しません。

方法1

したがって、まだヘッドノードに戻る必要があります。リンクリスト全体にはn個のノードがあり、下からK番目はn-k +1個のノードです。重要なのはnを取得することです。nがある場合は、最初からn-k +1ステップ戻ります。nを取得する方法は?1回繰り返すと、カウントを取得できます。
この方法では、最初にノード数をカウントし、2回目に下からK番目のノードを見つけるために、リンクリストの両側をトラバースする必要があります。
それで、一度だけ繰り返す方法はありますか?もちろんあります

方法2

トラバーサルを完了できることを実現するには、2つのポインターを定義する必要があります。
最初のポインターはリンクリストのヘッドポインターからトラバースを開始し、K-1ステップ進みます。2番目のポインターは静止したままで、ステップKから開始し、2番目のポインターもリンクリストのヘッドポインターからトラバースを開始します。
2つのポインター間の距離をk-1に保ちます。フロントポインターがテールノードに到達すると、バックポインターは実際には下からK番目のノードを指します。

例を示します。合計6つのノードがあります。下から3番目のノードを見つけます。
図は次のとおりです。
ここに画像の説明を挿入

コード

コードを書く前に、いくつかの特殊なケースも削除する必要があり
ます。1。入力pListHeadがnullポインターです。nullポインタが指すコンテンツに直接アクセスすると、プログラムがクラッシュします
。2。pListHeadをヘッドノードとする入力リンクリスト内のノードの総数がk未満です。再循環はリンクリスト上でkステップ進むため、nullポインタの問題が原因でクラッシュします。3。
入力パラメータは0です。kは符号なし整数であるため、forではk-1は-1ではありません。ループ。、しかし4294967295(0xFFFFFFFF)なので、forループの実行数は予想をはるかに超えており、これもクラッシュの原因になります。

ListNode* FindKthToTail(ListNode* pListHead,unsigned int k)
{
    
    
	if(pListHead==nullptr || k==0)
		return nullptr;
	ListNode* pAhead=pListHead;
	ListNode* pBehind=nullptr;

	for(unsigned int i=0;i<k-1;++i)
	{
    
    
		if(pAhead->mpNext!=nullptr)
			pAhead=pAhead->m_pNext;
		else
			return nullptr;
	}
	pBehind=pListHead;
	while(pAhead->m_pNext!=nullptr)
	{
    
    
		pAhead=pAhead->m_pNext;
		pBehind=pBehind->m_pNext;
	}
	return pBehind;
}

おすすめ

転載: blog.csdn.net/rjszz1314/article/details/104334787
おすすめ