链表题目汇总

经典题目参考:

https://blog.csdn.net/walkinginthewind/article/details/7393134

 

167. 链表求和

你有两个用链表代表的整数,其中每个节点包含一个数字。数字存储按照在原来整数中相反的顺序,使得第一个数字位于链表的开头。写出一个函数将两个整数相加,用链表形式返回和。

样例

样例 1:

输入: 7->1->6->null, 5->9->2->null
输出: 2->1->9->null	
样例解释: 617 + 295 = 912, 912 转换成链表:  2->1->9->null

样例 2:

输入:  3->1->5->null, 5->9->2->null
输出: 8->0->8->null	
样例解释: 513 + 295 = 808, 808 转换成链表: 8->0->8->null


对题目理解不好,数据类型换成long 解答:通过70%

class Solution {
public:
/**
* @param l1: the first list
* @param l2: the second list
* @return: the sum list of l1 and l2 
*/
ListNode * addLists(ListNode * l1, ListNode * l2) {
// write your code here
stack<int> res1,res2;

if(l1==NULL ){
return l2;
}

if(l2==NULL){
return l1;
}

while(l1!=NULL){

res1.push(l1->val);
l1=l1->next;

}

while(l2!=NULL){

res2.push(l2->val);
l2=l2->next;
}

int len1=res1.size();
int len2=res2.size();

int num1 = 0;
while(len1--){
int temp1=res1.top()*pow(10,len1);
res1.pop();

num1 = num1+temp1;

}

int num2 = 0;
while(len2--){
int temp2=res2.top()*pow(10,len2);
res2.pop();

num2 = num2+temp2;

}

int num = num1+num2;


cout<<num<<endl;
vector<int> result;

while(num>=10){
int temp = num%10;
result.push_back(temp);

num=num/10;

}

result.push_back(num);

int l = result.size();
cout<<l<<endl;

ListNode* head = new ListNode(result[0]);

ListNode * temp =head;
for(int i=1;i<l;i++){

ListNode* node = new ListNode(result[i]);
cout<<node->val<<endl;
temp->next=node;
temp = node;
}

 

return head;

}
};

  

 

优秀解法:

/**
 * Definition of singly-linked-list:
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *        this->val = val;
 *        this->next = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
    * @param l1: the first list
    * @param l2: the second list
    * @return: the sum list of l1 and l2
    */
    ListNode *addLists(ListNode *l1, ListNode *l2) {
        // write your code here
        ListNode *head = new ListNode(0);
        ListNode *end = head;
        ListNode *curr1 = l1;
        ListNode *curr2 = l2;
        int carry = 0;
        // 深入理解题目,求和进位进到后面去了,所以从前往后遍历就行
        while (curr1 != nullptr || curr2 != nullptr || carry != 0)
        {
            int a1 = 0;
            int a2 = 0;
            if (curr1 != nullptr)
            {
                a1 = curr1->val;
                curr1 = curr1->next;
            }
            if (curr2 != nullptr)
            {
                a2 = curr2->val;
                curr2 = curr2->next;
            }
            int sum = a1 + a2 + carry;
            carry = sum / 10;
            sum %= 10;
            ListNode *curr = new ListNode(sum);
            end->next = curr;
            end = curr;
        }
        return head->next;
    }
};

  

 

 

165. 合并两个排序链表

 

将两个排序链表合并为一个新的排序链表

样例

样例 1:
	输入: list1 = null, list2 = 0->3->3->null
	输出: 0->3->3->null


样例2:
	输入:  list1 =  1->3->8->11->15->null, list2 = 2->null
	输出: 1->2->3->8->11->15->null

 

/**
 * Definition of singly-linked-list:
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *        this->val = val;
 *        this->next = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param l1: ListNode l1 is the head of the linked list
     * @param l2: ListNode l2 is the head of the linked list
     * @return: ListNode head of linked list
     */
    ListNode * mergeTwoLists(ListNode * l1, ListNode * l2) {
        // write your code here
        
        if(l1 ==NULL){
            return l2;
        }
        
        if(l2== NULL){
            return l1;
        }
        
        ListNode * head= NULL;
        
        
        if(l1->val >= l2->val){
            head=l2;
            head->next = mergeTwoLists(l1,l2->next);
        }
        else{
            head=l1;
            head->next = mergeTwoLists(l1->next,l2);
        }
        
        return head;
        
        
    }
};

  

翻转链表:

 

/**
 * Definition of singly-linked-list:
 *
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *        this->val = val;
 *        this->next = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param head: n
     * @return: The new head of reversed linked list.
     */
    ListNode * reverse(ListNode * head) {
        // write your code here

        if(head == NULL || head->next == NULL){
        	return head;
        }

        ListNode * head_new = NULL;
        ListNode * cur = head;

        while(cur!=NULL){
        	ListNode * temp = cur;
        	cur = cur->next;

        	ListNode * head_pre= head_new;

        	head_new =temp;

        	head_new->next = head_pre;
        	head_new->val=temp->val;

        }

        return head_new;

    }
};

  

// 找到单链表倒数第n个节点,保证链表中节点的最少数量为n。

// 样例
// Example 1:
// Input: list = 3->2->1->5->null, n = 2
// Output: 1

// 当语言有问题时,可以重置一下



class Solution {
public:
    /*
     * @param head: The first node of linked list.
     * @param n: An integer
     * @return: Nth to last node of a singly linked list. 
     */
    ListNode * nthToLast(ListNode * head, int n) {
        // write your code here
        // 双指针问题解决
        if(head==NULL || n<=0 ){
        	return NULL;
        }

        ListNode *fast=head;
        ListNode *slow=head;

        while(n--){
        	fast = fast->next;
        }

        while(fast!=NULL){
        	fast = fast->next;
        	slow = slow->next;
        }
        
        return slow;
    }
};

  

 

102. 带环链表

给定一个链表,判断它是否有环。

样例

```
样例 1:
	输入: 21->10->4->5,  then tail connects to node index 1(value 10).
	输出: true
	
样例 2:
	输入: 21->10->4->5->null
	输出: false

```

挑战

不要使用额外的空间

 

/**
 * Definition of singly-linked-list:
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *        this->val = val;
 *        this->next = NULL;
 *     }
 * }
 */


class Solution {
public:
    /**
     * @param head: The first node of linked list.
     * @return: True if it has a cycle, or false
     */
    bool hasCycle(ListNode * head) {
        // write your code here
        if(head==NULL || head->next==NULL){
        	return false;
        }

        ListNode* slow = head;
        ListNode* fast = head;
        
        // 注意,这里要避免野指针出现,判断快指针是否到头即可
        while(fast !=NULL && fast->next !=NULL){
        	slow = slow->next;
        	fast = fast->next->next;
        	if(slow == fast){
        		return true;
        	}

        }

        return false;

    }
};

  

 

给出一个所有元素以升序排序的单链表,将它转换成一棵高度平衡的二叉搜索树

样例

样例 1:
	输入: array = 1->2->3
	输出:
		 2  
		/ \
		1  3
		
样例 2:
	输入: 2->3->6->7
	输出:
		 3
		/ \
	       2   6
		     \
		      7

	解释:
	可能会有多个符合要求的结果,返回任意一个即可。

 

 

/**
 * Definition of ListNode
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *         this->val = val;
 *         this->next = NULL;
 *     }
 * }
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */


// class Solution {
// public:
//     /*
//      * @param head: The first node of linked list.
//      * @return: a tree node
//      */
//     TreeNode * sortedListToBST(ListNode * head) {
//         // write your code here

//         if(head==NULL){
//         	return NULL;
//         }

//         if(head->next==NULL){
//         	TreeNode* t_node=new TreeNode(head->val);
//         	return t_node;
//         }


//         if(head->next->next==NULL){
//         	TreeNode* t_node=new TreeNode(head->val);
//         	t_node->right = new TreeNode(head->next->val);
//         	return t_node;
//         }


//         int len = 0;
//         ListNode * temp = head;
//         while(temp){
//         	len++;
//         	temp = temp->next;
//         }

//         int mid = len/2;

//         ListNode * mid_node = head;
//         while(mid--){
//         	mid_node = mid_node->next;
//         }

//         ListNode * mid_next = mid_node->next;
//         mid_node->next == NULL;

//         TreeNode* root = new TreeNode(mid_node->val);
        
//         root->left = sortedListToBST(head);
//         root->right = sortedListToBST(mid_next);


//         return root;


//     }
// };



class Solution {
public:
    TreeNode* sortedListToBST(ListNode* head) {
        vector<int> v;
        ListNode* cur=head;
        while(cur!=NULL){
            v.push_back(cur->val);
            cur=cur->next;
        }
        TreeNode* root=buildBST(v,0,v.size()-1);
        return root;
    }
    TreeNode* buildBST(vector<int>& nums,int l,int r){
       if(l>r)  return NULL;
        int mid=(l+r)/2;
        auto node= new TreeNode(nums[mid]);
        node->left=buildBST(nums,l,mid-1);
        node->right=buildBST(nums,mid+1,r);
        return node;
    }
};

  

 

剑指 Offer 52. 两个链表的第一个公共节点

输入两个链表,找出它们的第一个公共节点。

如下面的两个链表:

 

在节点 c1 开始相交。

 

示例 1:

 

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 8
输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(headA==NULL || headB==NULL){
            return NULL;
        }

        ListNode *A = headA;
        int lenA=0;
        ListNode *B = headB;
        int lenB=0;

        while(A!=NULL){
            lenA++;
            A=A->next;
        }
        while(B!=NULL){
            lenB++;
            B=B->next;
        }
        int step= 0;
        ListNode *tempA=headA;
        ListNode *tempB=headB;
        if(lenA>lenB){
            step= lenA-lenB;
            while(step){
                tempA=tempA->next;
                step--;
            }
            while(tempA!=NULL&&tempB!=NULL){
                if(tempA==tempB){
                    return tempA;
                }
                tempA=tempA->next;
                tempB=tempB->next;
            }

        }else{
            step= lenB-lenA;
            while(step){
                tempB=tempB->next;
                step--;
            }

            while(tempA!=NULL&&tempB!=NULL){
                if(tempA==tempB){
                    return tempA;
                }
                tempA=tempA->next;
                tempB=tempB->next;
            }


        }

        return NULL;





    }
};

  

思路:快慢指针

遍历两个链表,然后计算两个链表的节点数量,计算两个链表的节点数量差;

然后重新开始遍历,节点多的链表先开始,走多出来的节点个步数,然后节点少的链表和节点多的链表同时开始遍历,当指向的位置相同时,即为第一个交点;

 

 

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

 

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
  1->4->5,
  1->3->4,
  2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

示例 2:

输入:lists = []
输出:[]

示例 3:

输入:lists = [[]]
输出:[]

 

提示:

  • k == lists.length
  • 0 <= k <= 10^4
  • 0 <= lists[i].length <= 500
  • -10^4 <= lists[i][j] <= 10^4
  • lists[i] 按 升序 排列
  • lists[i].length 的总和不超过 10^4

 

两种思路:

1)使用优先队列的方法,每个链表取一个元素放入优先队列,每次从优先队列里取最小的那个元素

2)归并排序的思想,有序链表两两合并

 

https://blog.csdn.net/aikudexue/article/details/90769813

 

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        priority_queue<ListNode*, vector<ListNode*>, compare> q;
        for (auto l : lists) {
            if (l) {
                q.push(l);  //每个链表取一个元素放入优先队列
            }
        }
        
        ListNode pre(0);  //新建一个头结点,可以防止丢失最终链表的头
        ListNode *node = &pre
        while (q.size()) {
            ListNode *top = q.top();  //从优先队列里取最小的那个元素
            q.pop();
            node->next = top;  //将弹出的那个元素连到最终链表上
            node = node->next;  //指针向后移一步
            if (top->next) {
                q.push(top->next); //将下一个元素入队列
            }
        }
        return pre.next;
    }
    
    struct compare {
        bool operator()(const ListNode* l1, const ListNode* l2) {
            return l1->val > l2->val;
        }
    };
};

  

  

  

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
// class Solution {
// public:
//     ListNode* mergeKLists(vector<ListNode*>& lists) {
//         priority_queue<ListNode*, vector<ListNode*>, compare> q;
//         for (auto l : lists) {
//             if (l) {
//                 q.push(l);  //每个链表取一个元素放入优先队列
//             }
//         }
        
//         ListNode pre(0);  //新建一个头结点,可以防止丢失最终链表的头
//         ListNode *node = ⪯
//         while (q.size()) {
//             ListNode *top = q.top();  //从优先队列里取最小的那个元素
//             q.pop();
//             node->next = top;  //将弹出的那个元素连到最终链表上
//             node = node->next;  //指针向后移一步
//             if (top->next) {
//                 q.push(top->next); //将下一个元素入队列
//             }
//         }
//         return pre.next;
//     }
    
//     struct compare {
//         bool operator()(const ListNode* l1, const ListNode* l2) {
//             return l1->val > l2->val;
//         }
//     };
// };

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        return partition(lists, 0, lists.size()-1); //合并0-(size-1)的链表
    }
    
    ListNode* partition(vector<ListNode*>& lists, int start, int end){
        if(start == end){
            return lists[start];
        }
        
        if(start < end){
            int mid = (end+start)/2;
            
            ListNode* l1 = partition(lists, start, mid);  //合并start->mid的链表
            ListNode* l2 = partition(lists, mid+1, end);  //合并mid+1到end的链表
            //partition最终递归到最后还是两个链表的合并.举个例子来说比如合并6个链表,那么按照分治法,我们首先分别合并1和4,2和5,3和6。这样下一次只需合并3个链表,我们再合并1和3,最后和2合并就可以了。
            return merge(l1, l2); 
        }
        
        return NULL;
    }
    
    ListNode* merge(ListNode* l1, ListNode* l2){  //合并L1,L2两个有序链表
        if(!l1) return l2;
        if(!l2) return l1;
        
        if(l1->val < l2->val){
            l1->next = merge(l1->next, l2);
            return l1;
        }else{
            l2->next = merge(l1, l2->next);
            return l2;
        }
    }
};

  

重新写的思路:
1)先合并两个

2)然后两两合并

class Solution {
public:
     ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode *newHead=new ListNode(0);
        ListNode *head=newHead;
 
           while(l1!=NULL&&l2!=NULL){
                if(l1->val>l2->val){
                    newHead->next=l2;
                    l2=l2->next;
                    newHead=newHead->next;
                }else{
                    newHead->next=l1;
                    l1=l1->next;
                    newHead=newHead->next;
                }
                
            }
            if(l1!=NULL&&l2==NULL){
                newHead->next=l1;
                
            }else if(l1==NULL&&l2!=NULL){
                newHead->next=l2;
            }
        
        return head->next;
        }
 
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.size()==0){
            return NULL;
        }

		int interval =1;
		int len = lists.size();

		while(interval<len){
			for(int i=0;i<len-interval;){
				lists[i]=mergeTwoLists(lists[i],lists[i+1]);
				i=i+interval*2;
			}
			interval = interval*2;
		}

		return lists[0];
    }
};

  

 

 

 

 

 

 

19. 删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗?


思路:快慢指针实现,但需要注意链表中删除头节点的情况特殊处理;

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {

        // 双指针问题解决
        if(head==NULL || n<=0 ){
            return NULL;
        }

        if(head->next==NULL){
            return NULL;
        }

        ListNode *fast=head;
        ListNode *slow=head;
 
        while(n--){
            fast = fast->next;
        }

        ListNode * temp = NULL;

        while(fast!=NULL){
            fast = fast->next;
            temp = slow;
            slow = slow->next;
        }
        if(slow==head){
            ListNode * head_new = slow->next;
            slow->next = NULL;
            return head_new;
        }
        else{
            temp->next= slow->next;
            slow->next=NULL;
        }

        return head;

    }
};

  

83. 删除排序链表中的重复元素
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

示例 1:

输入: 1->1->2
输出: 1->2
示例 2:

输入: 1->1->2->3->3
输出: 1->2->3

 

思路:很简单,遍历链表,因为链表有序,依次比较当前元素和下一个元素是否相等,相等则删除下一个元素,将链表指针重新指向;
递归这个过程,直到链表结束,一次AC

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(head==NULL||head->next==NULL){
            return head;
        }

        ListNode* cur = head;

        while(cur->next!=NULL){
            if(cur->val==cur->next->val){
                cur->next=cur->next->next;
                deleteDuplicates(head);
            }
            else{
                cur=cur->next;
            }
        }

        return head;
    }
};

  

61. 旋转链表
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。

示例 1:

输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
示例 2:

输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL


解题思路:
step1:将链表首位相连成环;
step2:在k = list_len - k % list_len处断开。

如果理解起来比较抽象,可以画个图帮助理解,找到断开点以及返回新的头节点;
注意链表遍历cur和cur2不要用错,--k 还是 k--要验证清楚

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        
        if(head==NULL){
            return head;
        }
        
        ListNode* cur = head;
        ListNode* cur2 = head;
        int len = 1;
        while(cur->next!=NULL){
            cur= cur->next;
            len++;
        }
        
        cur->next = head;
        
        k = len-k%len;
        while(--k){
            cur2=cur2->next;
        }
        ListNode* head_new = cur2->next;
        cur2->next=NULL;
        
        return head_new;
        
    }
};

  

思路参考:https://blog.csdn.net/starzyh/article/details/90345257

 

 

138. 复制带随机指针的链表
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。

要求返回这个链表的 深拷贝。

我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。

思路:
第一次遍历链表的时候,复制旧链表的节点值建立一个新的链表,同时定义一个 unordered_map 作为哈希表,哈希表的键为旧链表的节点指针,值为新链表的节点指针。

然后,第二次遍历链表,访问旧链表节点的随机指针,然后以此为键从 map 中取出对应的新链表节点指针,这也就是当前新链表节点的随机指针。

https://www.cnblogs.com/seniusen/p/10142869.html

 

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/


class Solution {
public:
    Node *copyRandomList(Node *head) {
        
        unordered_map<Node *, Node *> nodemap;
        Node *temp = head;
        Node *new_head = new Node(0); //哨兵节点,方便操作
        Node *copy_temp = new_head;
 
        // 建立新链表
        while (temp)
        {
            copy_temp->next = new Node(temp->val);
            nodemap[temp] = copy_temp->next;
            
            temp = temp->next;
            copy_temp = copy_temp->next;
        }
        
        Node *random_temp = NULL;
        temp = head;
        copy_temp = new_head->next;
        // 填充新链表的随机指针
        while (temp)
        {
            random_temp = temp->random;
            if (random_temp != NULL)   copy_temp->random = nodemap[random_temp];
            else    
                copy_temp->random = NULL;
            
            temp = temp->next;
            copy_temp = copy_temp->next;
        }
        
        return new_head->next;
    }
};

  

876. 链表的中间结点
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。

 

示例 1:

输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
示例 2:

输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。


思路:快慢指针,注意奇数个节点和偶数个节点,设置一个标志未来处理
1--2--3--4--5
1--2--3--4

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        if(head ->next == NULL){
            return head;
        }
        if(head->next->next==NULL){
            return head->next;
        }

        ListNode* slow = head;
        ListNode* fast =head;

        int flag =1;
        while(fast->next!=NULL&&fast->next->next!=NULL){
            fast = fast->next->next;
            slow = slow->next;
        }

        if(fast->next!=NULL){
            flag=0;
        }

        if(flag==0){
            return slow->next;
        }

        return slow;

    }
};

  

 




 
posted @ 2020-09-10 19:28  静悟生慧  阅读(204)  评论(0编辑  收藏  举报