Longest Arithmetic Sequence - Question 1

Question 1: Given an array, please get the length of the longest arithmetic sequence. The element order in the arithmetic sequence should be same as the element order in the array. For example, in the array {1, 6, 3, 5, 9, 7}, the longest arithmetic sequence is 1, 3, 5, and 7, whose elements have same order as they are in the array, and the length is 4.

参考: http://codercareer.blogspot.com/2014/03/no-53-longest-arithmetic-sequence.html

最妙的是如何计算等差数列长度。请看参考链接,确实是很妙啊!

/* Copyleft: Ming Lin <minggr@gmail.com> */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct pair {
	int diff;
	int i, j;
	struct pair *next;
};

struct pair_list {
	int diff;
	struct pair *head;
	struct pair *tail;
	struct pair_list *chain;
};

struct hash {
	struct pair_list **head;
	int size;
};

struct hash *init_hash(int n)
{
	struct hash *h;
	struct pair_list **p;
	int size;

	h = malloc(sizeof(*h));
	size = n*sizeof(struct pair_list *);
	p = malloc(size);
	memset(p, 0, size);
	h->head = p;
	h->size = n;

	return h;
}

int hash_index(struct hash *h, int key)
{
	if (key < 0)
		key = -key;
	return key % h->size;
}

int mycount = 0;
void pair_add(struct pair_list **head, struct pair *p)
{
	struct pair_list *pl, *prev_pl;

	if (!*head) {
		pl = malloc(sizeof(struct pair_list));
		pl->diff = p->diff;
		pl->head = pl->tail = p;
		pl->chain = NULL;
		*head = pl;
		return;
	}

	pl = prev_pl = *head;

	while (pl && pl->diff != p->diff) {
		prev_pl = pl;
		pl = pl->chain;
	}

	if (pl) {
		pl->tail->next = p;
		pl->tail = p;
	} else {
		pl = malloc(sizeof(struct pair_list));
		pl->diff = p->diff;
		pl->head = pl->tail = p;
		pl->chain = NULL;
		prev_pl->chain = pl;
	}
}

void hash_add_pair(struct hash *h, struct pair *p) {
	int i;

	i = hash_index(h, p->diff);
	mycount++;
	pair_add(&h->head[i], p);
}

void hash_add(struct hash *h, int diff, int i, int j)
{
	struct pair *p;

	p = malloc(sizeof(struct pair));
	p->diff = diff;
	p->i = i;
	p->j = j;
	p->next = NULL;

	hash_add_pair(h, p);
}

void hash_build(struct hash *h, int data[], int n)
{
	int i, j;

	for (i = 0; i < n; i++) {
		for (j = i + 1; j < n; j++) {
			hash_add(h, data[j]-data[i], i, j);
		}
	}
}

void pair_list_dump_one(int *data, struct pair_list *pl)
{
	struct pair *p;

	p = pl->head;
	printf("  diff %d: ", pl->diff);
	while (p) {
		printf("{%d,%d -> %d,%d} ", p->i, p->j, data[p->i], data[p->j]);		
		p = p->next;
	}
	printf("\n");
}

void pair_list_dump(int *data, struct pair_list *pl)
{
	while (pl) {
		pair_list_dump_one(data, pl);
		pl = pl->chain;
	}	
}

void hash_dump(struct hash *h, int *data)
{
	int i;

	for (i = 0; i < h->size; i++) {
		printf("index %d\n", i);
		pair_list_dump(data, h->head[i]);
	}
}

int pair_list_len_one(struct pair_list *pl, int *len, int n)
{
	struct pair *p;
	int max = 0;

	while (n >= 1) {
		n--;	
		len[n] = 1;
	}

	p = pl->head;
	while (p) {
		len[p->j] = len[p->i] + 1;
		if (len[p->j] > max)
			max = len[p->j];
		p = p->next;
	}

	return max;
}

int pair_list_len(struct pair_list *pl, int *len, int n)
{
	int max = 0;

	while (pl) {
		int tmp = pair_list_len_one(pl, len, n);
		if (tmp > max)
			max = tmp;
		pl = pl->chain;
	}

	return max;
}

int length_of_longest_arithmetic_sequence(struct hash *h)
{
	int *len;
	int max = 0;
	int i;

	len = malloc(h->size * sizeof(int));
	for (i = 0; i < h->size; i++) {
		int tmp = 0;

		if (h->head[i])
			tmp = pair_list_len(h->head[i], len, h->size);
		if (tmp > max)
			max = tmp;
	}

	return max;
}

int main()
{
	struct hash *h;
	//int data[] = {1, 6, 3, 5, 9, 7};
	//int n = 6;
	int data[] = { 1, 8, 3, 6, 5, 4, 7, 2, 9 };
	int n = 9;

	h = init_hash(n);
	hash_build(h, data, n);
	hash_dump(h, data);
	printf("length_of_longest_arithmetic_sequence=%d\n", length_of_longest_arithmetic_sequence(h));

	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值