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;
}
本文介绍了一种求解数组中最长等差数列的方法。通过构建哈希表存储数列差值及其位置关系,实现了高效查找。示例代码展示了算法实现细节。
1万+

被折叠的 条评论
为什么被折叠?



