落单元素查找
描述
整型数组中除一个元素外其它元素都重复出现 n 次,找出落单的元素,需保证时间复杂度在 O(n) 以内。
考虑 n = 2, n = 3 的情形;
考虑除了一个元素出现 m 次,其它元素出现 n 次的情形, 其中 m != n。
示例:
给定数组 array = [1, 1, 1, 11, 11, 3, 3, 3, 4, 4, 4], 所以 m=2, n=3, 查找到目标元素为 11。
Delphi 算法
/*
* @param array 目标数组
* @param len 数组元素个数
* @param n 普通元素出现次数
* @return 查找到的特殊出现次数的元素值
* */
int find(int array[], int len, int n)
{
int ret = 0;
for (int i=0, tmp = 0; i<32; ++i, tmp=0)
{
for (int j=0; j<len; ++j)
{
tmp += (array[j] >> i) & 0x01;
}
ret |= !!(tmp % n) << i;
}
return ret;
}
原理
将目标数组分解为二进制矩阵后进行组合。
==> 数组中各元素 [0-31] 位累加
==> 累加和取余普通元素出现次数
==> 非0值转化为1
==> 转换为 int
11
栈实现及最小元素获取
描述:
初始问题:实现一个栈;
扩展问题1:添加一个操作 min(),获取当前栈中最小元素值;
扩展问题2:min() 的时间复杂度是否最优?为什么?
扩展问题3:整体空间复杂度是否最优?为什么?
方法一:借助辅助数据结构
template<typename T>
class stack
{
public:
void push(const T &obj)
{
m_mainList.push_front(obj);
if ((m_minList.size() == 0) || (obj < m_minList.front()))
m_minList.push_back(obj);
else
m_minList.push_back(m_mainList.front());
}
T top() const
{
return m_mainList.back();
}
void pop()
{
m_mainList.pop_back();
m_minList.pop_back();
}
T min() const
{
return m_minList.back();
}
size_t size() const
{
return m_mainList.size();
}
private:
list<T> m_mainList;
list<T> m_minList;
};
min() 时间复杂度:O(1)
min() 空间复杂度:O(n) [辅助链表]
方法二:仅适用于整形元素
template<int MAX>
class stack_int
{
public:
void push(const int v)
{
int d = m_min - v;
m_list.push_back(d);
if (d > 0)
m_min = v;
}
int top()
{
int ret = 0;
int d = m_list.back();
if (d < 0)
{
ret = m_min - d;
}
else
{
ret = m_min;
m_min = m_min + d;
}
return ret;
}
void pop()
{
int d = m_list.back();
if (d > 0)
{
m_min = m_min + d;
}
m_list.pop_back();
}
int min() const
{
return m_min;
}
size_t size() const
{
return m_list.size();
}
private:
list<int> m_list;
int m_min = MAX;
};
min() 时间复杂度:O(1)
min() 空间复杂度:O(1)
注
此算法仅适用于整形元素(char,short,int,long 等);
浮点型元素的计算及存储是不精确的,因此无法使用此数据结构。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。