博文视点微博上提出的两个问题



原本打算在新浪长微博上发,但是尼玛总提示敏感信息,我了个去,只好该在这里发了

ps:微博@骑猪猪吹泡泡


题目一主要思路

把原问题转化成求两个小集合的子集和的问题,遍历原数组,为保持原数据不造破坏,正负数置于另外申请的空间,把负数转成正数存储,同时判断原数据是否有0元素的存在。将分开的正负数(现在变成两组正数集合假设为A,B)快排让其有序,同时进行优化,剔除不会参与求子集和的元素,也即,A中存在元素比B中所有元素的和都大,显然这样的元素无效,目的是尽可能减少元素个数以减少穷举子集和的次数。
然后选取元素个数少的集合来求子集和sum0,然后在另一集合中判断是否存在子集和等于sum0,同时在进入另一集合判断时仍就做优化处理,剔除集合中大于sum0的元素。总之就是尽量减少参与计算子集和的元素个数

代码如下


#include <iostream>
void quick_sort(int* input_array,int low,int high);
//判断input_array中元素是否存在子集和等于key,成功返回true 
bool judge_subset(int* input_array,int length,unsigned int key);
//主操作,判断input_array中是否存在子集和为0,成功返回true
bool judge_sum_zero(int* input_array,int array_length)
{
	if( 0==array_length || NULL==input_array)
		return false;
	int* sorted_array = new int[array_length];
	unsigned int posi_sum=0,nega_sum=0;
	unsigned int posi_count=0,nega_count=0;
	int nega_begin_pos=0,nega_end_pos=-1;
	int posi_begin_pos = array_length;
	int posi_end_pos = array_length-1;
	//将原数组中正负数分开存储
	for(size_t i=0; i<array_length; ++i)
	{
		if( 0==input_array[i])
		{
			delete[] sorted_array;
			return true;
		}
		else if(0<input_array[i])
		{
			sorted_array[--posi_begin_pos] = input_array[i];
			++posi_count;
			posi_sum += input_array[i];
		}
		else
		{
			sorted_array[++nega_end_pos] = -input_array[i];
			++nega_count;
			nega_sum += -input_array[i];
		}
	}
	if( !(nega_count && posi_count)||(nega_sum == posi_sum) )
	{
		delete[] sorted_array;
		return false;
	}
	quick_sort(sorted_array,nega_begin_pos,nega_end_pos);
	quick_sort(sorted_array,posi_begin_pos,posi_end_pos);
	for(size_t i=nega_end_pos; i<=nega_begin_pos; --i)
	{
		if(sorted_array[i] == posi_sum)
		{
			delete[] sorted_array;
			return true;				
		}
		else if(sorted_array[i] < posi_sum)
			break;
		else
		{
			--nega_end_pos;
			--nega_count;
			nega_sum -= sorted_array[i];
		}
	}
	for(size_t i=posi_end_pos; i>=posi_begin_pos; --i)
	{
		if(sorted_array[i] == nega_sum)
		{	
			delete[] sorted_array;
			return true;
		}
		else if( sorted_array[i] <nega_sum)
			break;
		else
		{
			--posi_end_pos;
			--posi_count;
			posi_sum -= sorted_array[i];
		}
	}
	/*litter_array_begin_pos  为数量少的集合元素起点
	  litter_array_end_pos 为数量少的集合元素终点
	  big_array_begin_pos 为数量多的集合元素起点
	  big_array_end_pos  为数量多的集合元素终点
	  递增排序
	*/
	int litter_array_begin_pos,litter_array_end_pos;
	int big_array_begin_pos,big_array_end_pos;
	unsigned int litter_array_sum;
	unsigned int big_array_sum;
	if(nega_count<=posi_count)
	{
		litter_array_begin_pos = nega_begin_pos;
		litter_array_end_pos = nega_end_pos;
		litter_array_sum = nega_sum;
		big_array_begin_pos = posi_begin_pos;
		big_array_end_pos = posi_end_pos;
		big_array_sum = posi_sum;
	}
	else
	{
		
		litter_array_begin_pos = posi_begin_pos;
		litter_array_end_pos = posi_end_pos;
		litter_array_sum = posi_sum;
		big_array_begin_pos = nega_begin_pos;
		big_array_end_pos = nega_end_pos;
		big_array_sum = nega_sum;
	}
	int litter_array_count = litter_array_end_pos
							-litter_array_begin_pos+1;
	int j;
	unsigned int sum = big_array_sum;
	int begin_pos=big_array_begin_pos,end_pos;
	//开始计算数量少的集合的子集和
	for(unsigned int i=1; i<(1<<litter_array_count); ++i)
	{
		litter_array_sum = 0;
		end_pos = big_array_end_pos;
		sum = big_array_sum;
		for(j=0; j<litter_array_count; ++j)
		{
			if((i>>j)&0x01 ==0x01)
			{
				litter_array_sum += sorted_array[litter_array_begin_pos+j];
			}
			
		}
		while(end_pos >=begin_pos)
		{
			if(litter_array_sum == sorted_array[end_pos])
			{
				delete[] sorted_array;
				return true;
			}
			else if(litter_array_sum < sorted_array[end_pos])
			{
				sum -= sorted_array[end_pos];
				--end_pos;
				continue;
			}
			else
				break;
		}
		if(litter_array_sum == sum)
		{
			delete[] sorted_array;
			return true;
		}
		else if(litter_array_sum > sum)
			continue;
	
		if(end_pos<begin_pos)
			continue;
		if(judge_subset(&sorted_array[begin_pos]
						,end_pos-begin_pos+1
						,litter_array_sum))
		{
			delete[] sorted_array;
			return true;
		}
	}
	delete[] sorted_array;
	return false;
}
void swap(int& a,int&b)
{
	if(&a != &b)
	{
		a =a^b;
		b =a^b;
		a =a^b;
	}
}
int partion(int* input_array,int low,int high)
{
	int mid = low + (high-low)/2;
	if(input_array[low]>input_array[high]&&low<high)
		swap(input_array[low],input_array[high]);
	if(input_array[mid]<input_array[low])
		swap(input_array[mid],input_array[low]);
	if(input_array[mid]>input_array[high])
		swap(input_array[mid],input_array[high]);
	int temp = input_array[low];
	while(low<high)
	{
		while(input_array[high]>=temp && low<high)
			--high;		
		input_array[low] = input_array[high];
		while(input_array[low]<=temp && low<high)
			++low;
		input_array[high] = input_array[low];
	}
	input_array[low] = temp;
	return low;
}

void quick_sort(int* input_array,int low,int high)
{
	int pivot;
	if(low<high)
	{
		pivot = partion(input_array,low,high);
		quick_sort(input_array,low,pivot-1);
		quick_sort(input_array,pivot+1,high);
	}
}

bool judge_subset(int* input_array,int length,unsigned int key)
{
	if(length<1)
		return false;
	unsigned int sum;
	int j;	
	for(unsigned int i=1; i<(1<<(length)); ++i)
	{
		sum = 0;
		for(j=0; j<length; ++j)
		{
			if( ((i>>j)&0x01) ==0x01)
				sum += input_array[j];
			if(sum == key)
				return true;
			else if(sum >key)
				break;
		}
	}
	return false;
}

using namespace std;
int main()
{
	int a[]={-100,99,3,-5,300,-23,20,-102,45,9,-5,-5};
	std::cout<<"result is:"<<judge_sum_zero(a,sizeof(a)/sizeof(int));
	return 0;
}


题目二思路:

由于时间不多,没过多考虑就简单的这样处理,为结点添加4个域:

一个数据域,一个队列结构的next指针,一个用于有序结构指向前结点的sorted_prior指针,一个指向有序表的sorted_next指针,

所以,队列维护两个链表,一个用于满足队列结构的表,一个用于维护元素有序结构的表,添加双向的原因,主要考虑在删除结点时方便。


#include "stdafx.h"
#include <iostream>
template<class type>
class queue_node
{
public:
	queue_node(type value)
	{
		data = value;
		next = NULL;
		sorted_prior = NULL;
		sorted_next =NULL;		
	}
	~queue_node()
	{

	}
	type data;
	queue_node* next;
	queue_node* sorted_prior;
	queue_node* sorted_next;
};

template<class type>
class queue
{
public:
	queue()
	{
		head = NULL;
		tail = NULL;
		sorted_list = NULL;
		length = 0;
	}
	~queue()
	{
		if( 0 ==length)
			return;
		queue_node<type> *p = head;
		queue_node<type> *q = p->next;
		while(p)
		{
			delete p;
			p = q->next;
		}
	}
	//添加新结点
	void push_back(type data);
	//移除队头元素
	void pop();
	//获取队头元素,成功返回true,同时value的值为队头元素值
	bool get_head(type& value) const;  
	//获取队列最大元素
	bool get_max_value(type& value) const;
	//获取队列长度
	inline size_t get_length() const;
private:
	inline void rm_sorted_node(queue_node<type>* rm_node);
	inline void add_sorted_node(queue_node<type>* add_node);
private:
	queue_node<type>* head;
	queue_node<type>* tail;
	queue_node<type>* sorted_list;
	size_t length;	
};
template <class type> void 
queue<type>::push_back(type data)
{
	queue_node<type> *node = new queue_node<type>(data);	
	if (!length)
		head =tail = node;
	else	
	{
		tail->next = node;
		tail = tail->next;
	}
	++length;
	add_sorted_node(node);
}
template <class type> void 
queue<type>::pop()
{
	queue_node<type> *node = head;
	if (node)
	{	rm_sorted_node(node);
		head = head->next;
		delete node;
		--length;
	}
	if( !length)
		head = tail = NULL;
}
template <class type> inline size_t 
queue<type>::get_length() const
{
	return this->length;
}
template <class type> bool 
queue<type>::get_head(type& value) const
{
	if(!get_length())
		return false;
	value = head->data;
	return true;
}
template <class type> bool 
queue<type>::get_max_value(type& value) const
{
	if(sorted_list)
		value = sorted_list->data;
	else
		return false;
	return true;
}
template <class type> inline void 
queue<type>::rm_sorted_node(queue_node<type>* rm_node)
{
	if(!rm_node->sorted_prior)
	{
		sorted_list = rm_node->sorted_next;
		if(sorted_list)
		{
			sorted_list->sorted_prior = NULL;
		}
		return;
	}
	rm_node->sorted_prior->sorted_next = rm_node->sorted_next;
	if(rm_node->sorted_next)
		rm_node->sorted_next->sorted_prior = rm_node->sorted_prior;
}
template <class type> inline void 
queue<type>::add_sorted_node(queue_node<type>* add_node)
{
	if(!sorted_list)
	{
		sorted_list = add_node;
		return;
	}
	queue_node<type>* temp_node;
	temp_node = sorted_list;
	while(temp_node->sorted_next &&(temp_node->data > add_node->data))
			temp_node = temp_node->sorted_next;	
	if(!temp_node->sorted_next &&(temp_node->data > add_node->data))
	{
		add_node->sorted_prior = temp_node;
		temp_node->sorted_next = add_node;
	}
	else
	{
		add_node->sorted_next = temp_node;
		add_node->sorted_prior = temp_node->sorted_prior;		
		if(temp_node->sorted_prior)
			temp_node->sorted_prior->sorted_next = add_node;
		else
			sorted_list = add_node;
		temp_node->sorted_prior = add_node;
	}
}
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{

	queue<int> my_queue;
	int a[] = {213,435,32,34,54,65,2,776,32,65,21,43,23,55,76,23,76,88,43,12};
	for(int i=0;i<(sizeof(a)/sizeof(int));++i)
		my_queue.push_back(a[i]);
	int max = 0;
	my_queue.get_max_value(max);
	cout<<"最大值为:"<<max<<endl;
	for(int i=0;i<(sizeof(a)/sizeof(int)); ++i)
	{
		int value =0;
		my_queue.get_head(value);
		std::cout<<"移除元素"<<value<<endl;
		my_queue.pop();
		my_queue.get_max_value(max);
		cout<<"此时队列最大值为:"<<max<<endl;
	}

	return 0;
}





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值