昨天写了关于子数组的和等于特定值的算法。今天和大家分享求子数组的和最接近特定值,和等于特定值的区别在于只是建树的过程不太一样。需要插入,每个节点的时候记录与当前节点最接近的节点,并且将差值保存起来。差值越小说明越接近特定值。
struct Node{
Node* left;
Node* right;
int value;
int pos;
};
int g_min = -1;
int g_start=0;
int g_end =0;
Node* Left = NULL;
Node* Right =NULL;
bool InsertNode(Node* root, int value, int pos, int& start, int& end)
{
if(NULL == root)
{
return false;
}
if(root->value = value)
{
start = pos;
end = pos;
return true;
}
while(NULL != root)
{
if(root->value == value)
{
if(root->pos < pos)
{
start = root->pos;
end = pos;
}
else
{
end = root->pos;
start = pos;
}
return true;
}
else if(root->value < value)
{
if(root->right)
{
Left = root;
root = root->right;
}
else
{
if( value - Left->value < Right->value - value)
{
if(value - Left->value < g_min || g_min == -1)
{
g_min = value - Left->value;
if(Left->pos < pos)
{
start = Left->pos;
end = pos;
}
else
{
end = Left->pos;
start = pos;
}
}
}
else
{
if(value - Right->value < g_min || g_min == -1)
{
g_min = value - Right->value;
if(Right->pos < pos)
{
start = Right->pos;
end = pos;
}
else
{
end = Right->pos;
start = pos;
}
}
}
Node* newNode = new Node;
newNode->pos = pos;
newNode->value = value;
root->right = newNode;
return false;
}
}
else
{
if(root->left)
{
Right = root;
root = root->left;
}
else
{
Node* newNode = new Node;
newNode->pos = pos;
newNode->value = value;
root->left = newNode;
return false;
}
}
}
return false;
}
void FindSubArrayEqValue(int* A, int length, int S,int& start, int& end)
{
if(length < 1 || NULL == A)
{
start = -1;
end = -1;
return;
}
if(length ==1)
{
start = 0;
end = 0;
}
int* SUM = new int[length];
SUM[0] = A[0];
for(int i = 1; i < length; ++i)
{
SUM[i] = SUM[i - 1] + A[i];
}
Node* root = new Node;
root->pos = -1;
root->value = 0;
for(int i = 0; i < length; ++i)
{
if(InsertNode(root,SUM[i] - S, i,start,end))
{
printf("Find sub array from %d to %d equal %d", start, end, S);
return ;
}
}
printf("Find sub array from %d to %d near %d, distance is %d", g_start, g_end, S, g_min);
delete []SUM;
}