您的位置:首页 > 其它

约瑟夫环方法小结

2015-08-25 22:14 387 查看
题目:0,1,……,n-1这n个数排成一个圈,从数字0开始每次从这个圈里删除第m个数字。求这个圈里剩下的最后一个数。

解一:从题意可以看出这是一个循环链表的题目,我们可以建立一个循环链表,然后从头开始遍历,遍历到第m-1个节点时,删除其后一个节点,直到只含有一个节点,输出该节点的值即可。

代码:

typedef struct node//建立链表
{
node *next;
int data;
node() :data(-1), next(NULL){};
}node;

node* Createlist(int n)//建立循环链表
{
node *ret = NULL;
if (n > 1)
{
int i = 0;
node *p = new node;
p->data = i;
ret = p;
i++;
while (i <= n-1)
{
node *q = new node;
q->data = i;
p->next = q;
p = p->next;
i++;
}
p->next = ret;
}
else
{
ret = new node;
ret->data = 0;
ret->next = ret;
}
return ret;
}

int LastRemaining(unsigned int n, unsigned m)
{
if (n < 1 || m < 1)
return -1;
node *head = Createlist(n);

node *h = head;
m %= n;
while (h!=h->next)
{
int i = 1;
for (int i = 1; i < m-1; i++)
{
h = h->next;
}
cout << h->next->data<<" ";
node *temp = h->next;
h->next = h->next->next;
h = h->next;
delete temp;
}
//cout << h->data<<endl;
return h->data;
}

解法二:思想如同解一,但是可以利用STL中的list,但是注意遍历list的时候如果遍历到结尾处,则需要回到ist的头部,list.end()中没有存储数据。

代码:

int LastRemaining(unsigned int n, unsigned m)
{
if (n < 1 || m < 1)
return -1;
list<int> numbers;
for (int i = 0; i <n; i++)
{
numbers.push_back(i);
}

auto iter = numbers.begin();
while (numbers.size()>1)
{
for (int i = 1; i < m; i++)
{
iter++;
if (iter==numbers.end())//如果遍历到链表末尾,则需返回到头部
{
iter = numbers.begin();
}
}

auto next = ++iter;
if (next==numbers.end())
{
next = numbers.begin();
}

--iter;
numbers.erase(iter);
iter = next;
}
return *iter;
}


解法三:剑指offer上提供的方法。定义关于n和m的方程f(n,m),表示每次在n个数字0,1,……,n-1中每次删除第m个数字最后剩下的数字。在n个数中第一次被删除的是(m-1)%n,记为k。把剩余的n-1个数字重新排列,为k+1,……n-1,0,1,……k-1。接着做一个映射

k+1->0

k+2->1

……

n-1->n--2

0->n-k-1

1->n-k;

……

k-1->n-2

把该映射定义为p,则x->p(x)可表示成p(x)=(x-k-1)%n。其逆映射p‘(x)=(x+k+1)%n。 根据映射规则,映射之前的序列中最后剩下的数字f'(n-1,m)=f[(n-1,m)+k+1]%n,把k=(m-1)%n代入得到f(n,m)=f'(n-1,m)=[f(n-1,m)+m]%n。根据该递推公式我们可以求出f[n,m],注意当n=1时,f[n,m]=0。

代码:

int LastRemaining(unsigned int n, unsigned int m)
{
if (n < 1 || m < 1)
return -1;

int last = 0;
for (int i = 2; i <= n; i++)
{
last = (last + m) % i;
}

return last;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: