判断数组 a 中是否包含了数值 x
bool IsContained(int a[], int n, int x)
{
bool ret = false;
if(n > 0)
{
ret = (a[n - 1] == x) || IsContained(a, n - 1, x);
}
return ret;
}
判断数组 a 是否有序
bool IsOrdered(int a[], int n, bool min2max = true)
{
bool ret = true;
if(n > 1)
{
ret = (min2max ? (a[n - 1] >= a[n - 2]) : (a[n - 1] <= a[n - 2])) && IsOrdered(a, n - 1, min2max);
}
return ret;
}
查找数组 a 中的最大值
常规解法如下:
int MaxInArray(int a[], int begin, int end)
{
int ret = -9999;
if(begin == end)
{
ret = a[begin];
}
else
{
int bv = a[begin];
int rv = MaxInArray(a, begin + 1, end);
ret = (bv > rv) ? bv : rv;
}
return ret;
}
int MaxInArray(int a[], int n)
{
return MaxInArray(a, 0, n - 1);
}
这种解法的递归深度更深,它的空间复杂度更高
优化后的解法如下:
int MaxInArray(int a[], int begin, int end)
{
int ret = -9999;
if(begin == end)
{
ret = a[begin];
}
else
{
int mid = (begin >> 1) + (end >> 1) + (begin & end & 1); // 防止 begin + end 溢出,等价于 begin + (end - begin) / 2
int lmax = MaxInArray(a, 0, mid);
int rmax = MaxInArray(a, mid + 1, end);
ret = (lmax > rmax) ? lmax : rmax;
}
return ret;
}
int MaxInArray(int a[], int n)
{
return MaxInArray(a, 0, n - 1);
}
它的递归深度为常规解法的一半,它的空间复杂度更低。
求一个字符串的所有子集
DynamicArray<String> SubSet(String set)
{
DynamicArray<String> ret;
/* 当 set 为空时,只有一个空集 */
if(set.length() == 0)
{
ret.resize(1);
ret[0] = "";
}
/* 当 set 只有一个元素时,它的子集为空集和包含这一个元素的集合 */
else if(set.length() == 1)
{
ret.resize(2);
ret[0] = "";
ret[1] = set;
}
/* 当 set 大于一个元素时 */
else
{
ret = SubSet(set.sub(1)); // 求出除了第一个元素的这个字符串的所有子集
ret.resize(ret.length() * 2); // 将当前元素并入子集当中,所以这个数组要扩大到原来的2倍
/* 将 set 的第一个元素并入子集中,并将并入的集合放入数组空余位置处 */
for(int i = 0, j = ret.length() / 2; j < ret.length(); i++, j++)
{
ret[j] = String(set[0]) + ret[i];
}
}
return ret;
}
删除无序链表中的重复结点
思路如下图所示:
template<typename T>
class WorkList : public LinkList<T>
{
protected:
typedef typename LinkList<T>::Node Node;
/* 删除链表中的重复结点 */
void rmdup(Node* head)
{
if(head != nullptr)
{
rmdup(head->next); // 删除除去当前结点的子链表中的重复结点
rmdup(head, head->value); // 通过当前结点删除子链表中存在与当前结点值相同的结点
}
}
/* head 为头结点(待删除链表的前一个结点),通过 val 删除相同值的结点 */
void rmdup(Node* head, int val)
{
while(head->next != nullptr)
{
if(head->next->value == val)
{
Node* toDel = head->next;
head->next = toDel->next;
delete toDel;
}
else
{
head = head->next;
}
}
}
public:
void rmdup()
{
rmdup(this->m_header.next);
}
};