不刷题,永远不知道自己是多么菜,一刷题才发现自己学的是假计算机专业,希望自己能够坚持下去,在接下来的日子继续刷题,完整的看完《算法导论》。
记leetcode中的第一道困难级别的题
题目:给定一个整数数组 nums,按要求返回一个新数组 counts。
数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。
示例 :
输入 : [5, 2, 6, 1]
输出 : [2, 1, 1, 0]
解释 :
5 的右侧有 2 个更小的元素(2 和 1).
2 的右侧仅有 1 个更小的元素(1).
6 的右侧有 1 个更小的元素(1).
1 的右侧有 0 个更小的元素.
这道题其实,一看就发现不就是冒泡排序吗,两次循环就搞定了,啥也不说上代码:
vector<int> CAlgCountSmaller::countSmaller(vector<int>& nums)
{
vector<int> vecRetSmall;
int iArraySize = nums.size();
if (iArraySize < 1)
{
return vecRetSmall;
}
//!初始化vector数组
vecRetSmall.assign(iArraySize, 0);
for (size_t i = 0; i < iArraySize; i++)
{
for (int iSecond = i + 1; iSecond < iArraySize; iSecond++)
{
if (nums[iSecond] < nums[i])
{
vecRetSmall[i]++;
}
}
}
return vecRetSmall;
}
范例一下就测试通过了,感觉就这还困难级别吗?冒着忐忑的心态提交,果然超出时间限制,16个用例,通过了15个。
在平时写代码过程中,两次循环用的太多了,从来没考虑过效率问题。现在是时候要考虑了!
1.有没有重复的比较出现
答案是绝对有的.....
数组用 A={a1,a2....ai,....a(size)}; 0 < i < size;
假设第一次遍历后,有第a1 大于区间[a3,a100]所有的数,a1小于a2
那么,第二次遍历a2时,还需要再次遍历a3-a100之间的值吗?
当然不需要了,那么怎么才能避免这种冲突了,第一想法当然是记录下来已经比较的结果了,再次比较的时候,先于已经比较的进行判断,那么如何记录已经知道的结果呢?这不就是维护一个二叉搜素树吗?
好了,看代码吧,
class Solution {
public:
struct ST_TreeNode
{
//!节点值
int iValue;
//!左子树个数
int iCount;
//左子树
ST_TreeNode* m_pLeftNode;
//!右子树
ST_TreeNode* m_pRgintNode;
};
class ST_Tree
{
public:
ST_Tree(int iValue) :stRootNode{0,0,NULL,NULL} { stRootNode.iValue = iValue; }
void InsertNode(int iValue, int& iSmallCount)
{
pri_insert(&stRootNode, iValue, iSmallCount);
}
void pri_insert(ST_TreeNode* pNode, int iInsertValue, int& iSmallCount)
{
if (!pNode)
{
return;
}
//!新插入节点值大于当前节点值
if (iInsertValue > pNode->iValue)
{
iSmallCount += pNode->iCount + 1;
//!右节点为空,则创建新的节点
if (NULL == pNode->m_pRgintNode)
{
pNode->m_pRgintNode = new ST_TreeNode{ iInsertValue ,0, NULL, NULL };
}
//右节点不为空,则递归在右节点插入
else
{
pri_insert(pNode->m_pRgintNode, iInsertValue, iSmallCount);
}
}
//!新插入节点值小等于当前节点值
else
{
pNode->iCount++;
//!左节点为空,则创建新的节点
if (NULL == pNode->m_pLeftNode)
{
pNode->m_pLeftNode = new ST_TreeNode{ iInsertValue ,0, NULL, NULL };
}
//左节点不为空,则递归在左节点插入
else
{
pri_insert(pNode->m_pLeftNode, iInsertValue, iSmallCount);
}
}
}
//!树节点
ST_TreeNode stRootNode;
};
vector<int> countSmaller(vector<int>& nums) {
vector<int> vecSmall;
int iArraySize = nums.size();
if (iArraySize < 1)
{
return vecSmall;
}
ST_Tree stBSTree(nums[iArraySize -1]);
vecSmall.assign(nums.size(), 0);
for (int i = iArraySize - 2; i >= 0; --i) {
stBSTree.InsertNode(nums[i], vecSmall[i]);
}
return vecSmall;
}
};