一些常见的经典算法题及实现

TopK算法:

https://www.cnblogs.com/lxy-xf/p/11338652.html

二叉树的直径:

leetcode543:

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过根结点。

思路:

  很简单的遍历二叉树,根据子节点左右树的节点数来计算当前树下的最长长度,并更新全局最长长度。Core返回的是左右子树最长的一棵和根节点的和。

class Solution {
public:
    int diameterOfBinaryTree(TreeNode* root) {
		if(!root)
			return 0;
		g_max=INT_MIN;
		Core(root);
		return g_max;
    }
private:
	int Core(TreeNode* root)
	{
		if(!root)
			return 0;
		int left=Core(root->left);
		int right=Core(root->right);
		if(left+right+1>g_max)
			g_max=left+right;
		int result=(left>right)?left:right;
		return result+1;
	}
	int g_max;
};

二叉树展开为链表:

leetcode114:

  给定一个二叉树,原地将它展开为链表。

思路:

  当处理某个节点时,我们所要做的工作是:

  1).用right代表next,也就是说right要指向他原来左子树的根节点.

  2).这个节点原来的右子树现在要接到它原来左子树的最后一个节点的right上.

  3).将这个节点的left置NULL(因为是单向链表)

因此,我们递归的工作就是:

  将right指向原来的左子树,将原来左子树的最后一个节点的right接到这个节点原来的右子树的根节点上。

  置空left.

  返回这个新链表的最后一个节点,因为这个节点将可能是上一层某个节点的左子树的根节点。

  最后注意返回时的情况:如果这个节点没有右子树,则它返回的应该是它原来左子树的最后一个节点,如果这个节点没有左子树,则返回的应该是它右子树的最后一个节点。如果它左右子树都不存在应该返回自己。

class Solution {
public:
    void flatten(TreeNode* root) {
		if(!root)
			return;
		Core(root);
    }
	TreeNode* Core(TreeNode* root)
	{
		TreeNode* tmp=root->right;
		if(root->left)
		{
			root->right=root->left;
			root->left=NULL;
			TreeNode* lb=Core(root->right);
			if(tmp)
			{
				lb->right=tmp;
				return Core(tmp);
			}		
			else
				return lb;
		}
		else
		{
			if(tmp)
				return Core(tmp);
			else
				return root;
		}
	}
};

二叉树最近的公共祖先:

LeetCode 236:

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4]

 

思路:

两个节点的最近的公共节点代表着:从根节点到这个最近公共节点间的所有节点,都是遍历p与遍历q都要经过的,也就是说,如果要遍历到p,它一定要经过这段路径。

如果要遍历到q,也一定要经过这段路径。

因此如果我们得到遍历p与q的这两条路径,只要找到这两段路径上不相等的点,这个点前面一个节点就是最近的公共节点。

至于得到遍历某个节点的路径,可以通过回溯和一个vector来实现。

另外有一点要注意的是,如果p是q的子节点,那么p的路径将比q长,因此如果当q数组遍历完而p还没遍历完时,说明q.back()就是公共节点。

代码:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root)
			return root;
		vector<TreeNode*> auxp;
		vector<TreeNode*> auxq;
		Core(auxp,root,p);
		Core(auxq,root,q);
		for(int i=0;i<min(auxp.size(),auxq.size());i++)
		{
			if(auxp[i]!=auxq[i])
				return auxp[i-1];
		}
		return auxp.size()>auxq.size()?auxq.back():auxp.back();
    }
	bool Core(vector<TreeNode*>& arr,TreeNode* root,TreeNode* ans)
	{
		if(!root)
			return false;
		if(root==ans)
		{
			arr.push_back(root);
			return true;
		}
		arr.push_back(root);
		if(!Core(arr,root->left,ans)&&!Core(arr,root->right,ans))
		{
			arr.pop_back();
			return false;
		}
		return true;
	}
};

  

复原IP地址

leetcode 93

翻转链表

二叉排序树转双向链表

求一个数的平方根

原文地址:https://www.cnblogs.com/lxy-xf/p/11345095.html