zoukankan      html  css  js  c++  java
  • 剑指offer-找到两个叶子节点的最低公共节点,数组的逆序对的个数,第一个公共链表节点

    找到两个叶子节点的最低公共节点

    思路:

    1.若这棵树为二叉搜索树的话,根据特性,我们从根节点遍历,若两个叶子节点值都小于根节点值,则最低公共节点一定在左子树,都大于的话在右子树。当一个小于一个大于时,所到达的节点就是最低公共节点。
    2.若这棵树有父指针,那么问题可以转化为求链表的第一个公共节点的问题。
    3.若只是棵普通的二叉树,可以两次遍历树,找到根节点到叶子节点的路径并保存。再从路径中比较找出最后一个相同的节点。

    代码:

    list<TreeNode*> path;
    bool GetNodePath(TreeNode* root, TreeNode* pNode, list<TreeNode*>& path)//找到根到所求节点的路径。
    {
    	if (root == NULL)
    		return true;
    	path.push_back(root);
    	bool found = false;
    	if(!found)
    	{
    		found = GetNodePath(root->left, pNode, path);
    
    	}
    	if (!found)
    	{
    		found = GetNodePath(root->right, pNode, path);
    	}
    	if (!found)
    		path.pop_back();
    	return found;
    }
    TreeNode *GetLastCommonNode(list<TreeNode*> path1,list<TreeNode*> path2)//求两条路径的最后公共节点
    
    {
    	
    	list< TreeNode*>::iterator it1 = path1.begin();
    	list< TreeNode*>::iterator it2 = path2.begin();
    	TreeNode* plast = NULL;
    	while (it1 != path1.end() && it2 != path2.end())
    	{
    		if (*it1 == *it2)
    			plast = *it1;
    		it1++;
    		it2++;
    	}
    	return plast;
    }
    TreeNode* GetLastCommonParent(TreeNode* root, TreeNode* pNode, TreeNode* qNode)
    {
    	if (root == NULL || pNode == NULL || qNode == NULL)
    		return NULL;
    	list<TreeNode*> path1;
    	list<TreeNode*> path2;
    	bool p=GetNodePath(root, pNode, path1);
    	bool q=GetNodePath(root, qNode, path2);
    	if (p && q)
    	{
    		return GetLastCommonNode(path1, path2);
    	}
    	return NULL;
    }
    

    数组的逆序对的个数

    思路:

    采用归并排序的思想,每次归并时用两个指针指向两个数组,比较大小,出现逆序对就将计数器+1.

    代码:

    void Merge(int arr[], int l, int mid, int r, int *cnt)  //合并两个数组
    {
    	
    	int* help = new int[r - l + 1];  //辅助数组
    	int p1 = l;
    	int p2 = mid + 1;
    	int index = 0;
    	while (p1 <= mid && p2 <= r)
    	{
    		help[index++] = arr[p1] < arr[p2] ? arr[p1] : arr[p2];
    		if (arr[p1] > arr[p2])
    		{
    			(*cnt)+=mid-p1+1; //arr[p1]>arr[p2]时,因为p1后面到mid的数字递增,所以都是逆序的.
    			for (int i = p1; i <= mid; i++)
    			{
    				cout << arr[i] << ' ' << arr[p2] << endl;
    			}
    			p2++;
    			
    		}
    		else
    		{
    			p1++;
    		}
    	}
    	while (p1 <= mid)  //复制剩余的元素
    	{
    		help[index++] = arr[p1++];
    		
    	}
    	while (p2 <= r)
    	{
    		help[index++] = arr[p2++];
    	}
    	for (int i = 0; i < r - l + 1; i++) //复制到原数组
    	{
    		arr[l + i] = help[i];
    	}
    	delete[] help;
    }
    void MergeSort(int arr[], int l, int r,int *cnt)
    {
    	
    	if (l == r)
    		return;
    	if (l < r)
    	{
    		int mid = (l + r) / 2;
    		MergeSort(arr, l, mid,cnt);
    		MergeSort(arr, mid + 1,r,cnt);
    		Merge(arr, l, mid, r,cnt);
    	}
    	
    }
    int FindInversePairs(int arr[], int len)
    {
    	int cnt = 0;
    	if (len <= 0 || arr == NULL)
    	{
    		return 0;
    	}
        MergeSort(arr, 0, len - 1,&cnt);
    	return cnt;
    }
    

    第一个公共链表节点

    思路:

    1.从后往前找最后一个公共节点,但是单链表只能向前。最后遍历的节点却要最先访问,所以用两个栈来贮存源节点到尾节点的路径。需要辅助空间。
    2.可以先遍历一次链表分别得到长度,让长的链表先走几步,然后一起运动,就可以同时到达公共节点。

    代码:

    ListNode* FirstCommonListNode(ListNode* head1, ListNode* head2)
    {
    	if (head1 == NULL || head2 == NULL)
    	{
    		return NULL;
    	}
    	int len1 = 0;
    	int len2 = 0;
    	ListNode* p = head1;
    	while (p)
    	{
    		len1++;
    		p = p->next;
    	}
    	p = head2;
    	while (p)
    	{
    		len2++;
    		p = p->next;
    	}
    	if (len1 > len2)
    	{
    		for (int i = 0; i < len1 - len2; i++)
    		{
    			head1 = head1->next;
    		}
    	}
    	else if (len1 < len2)
    	{
    		for (int i = 0; i < len2 - len1; i++)
    		{
    			head2 = head2->next;
    		}
    	}
    	ListNode*p1 = head1;
    	ListNode* p2 = head2;
    	while (p1 && p2)
    	{
    		if (p1 == p2)
    			return p1;
    		else
    		{
    			p1 = p1->next;
    			p2 = p2->next;
    		}
    	}
    	return NULL;
    }
    
  • 相关阅读:
    Java Native Method
    SQL语句优化
    Ibatis的环境搭建以及遇到的问题解决
    Java 构建器
    SpringMVC自定义视图 Excel视图和PDF视图
    java 枚举的常见使用方法
    mysql 根据某些字段之和排序
    MFC The Screen Flickers When The Image Zoomed
    How To Debug Qmake Pro File
    Gcc And MakeFile Level1
  • 原文地址:https://www.cnblogs.com/void-lambda/p/12431667.html
Copyright © 2011-2022 走看看