leetcode-1. Sum of two numbers

The sum of the two numbers.

Given an array of integers nums and a target value target, please find the two integers with and as the target value in the array and return their array subscripts.

You can assume that each input corresponds to only one answer. However, the same element in an array cannot be used twice.

Example:

  Given nums = [2, 7, 11, 15], target = 9, because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].

Source: LeetCode
Link: https://leetcode-cn.com/problems/two-sum
Copyright belongs to the network. For commercial reprint, please contact the official authorization. For non-commercial reprint, please indicate the source.



Solution 1: the cycle of violence.
int *twoSum( int *nums, int numsSize, int target, int *returnSize ) {
	int *answer = NULL;

	returnSize[0] = 0;
	answer = malloc( sizeof(*answer) * 2 );
	for( int i = 0; i < numsSize; ++i ) {
		for( int j = i + 1; j < numsSize; ++j ) {
			if( target - nums[i] == nums[j] ) {
				answer[returnSize[0]++] = i;
				answer[returnSize[0]++] = j;
				break;
			}
		}
	}

	return answer;
}


Solution 2: use HashTable or HashMap to traverse the process twice.
// Package uthash start
#define ERROR_EXIT( expression ) \
if( (expression) ) exit( EXIT_FAILURE )

typedef void ( TraversalHashTableFunc )( int key, int value );

typedef struct NodeHashTable {
	int k;
	int v;
	UT_hash_handle hh;
} NodeHashTable, HashTable;

// Function: create a new hash table
// Parameter: none
// Return: NULL
// Note: the new table in uthash should be NULL initially
HashTable *newHashTable( void ) {
	return NULL;
}

// Function: add key value pair to hash table
// Parameters: HT, key, value
// Return: none
// Note: when ht is NULL, the program will exit in error. When the key exists, the key value will be updated to value
void putHashTable( HashTable **ht, int key, int value ) {
	NodeHashTable *n = NULL;

	ERROR_EXIT( ht == NULL );
	HASH_FIND_INT( *ht, &key, n );
	if( n == NULL ) {
		n = malloc( sizeof(*n) );
		n->k = key;
		HASH_ADD_INT( *ht, k, n );
	}
	n->v = value;
}

// Function: remove the key value pair from the hash table
// Parameters: HT (pointer to store the pointer of hash table object), key (key)
// Return: the removed key value
// Note: when ht is NULL or the key does not exist, the program will exit in error
int removeHashTable( HashTable **ht, int key ) {
	int value = 0;
	NodeHashTable *n = NULL;

	ERROR_EXIT( ht == NULL );
	HASH_FIND_INT( *ht, &key, n );
	ERROR_EXIT( n == NULL );
	HASH_DEL( *ht, n );
	value = n->v;
	free( n );

	return value;
}

// Function: whether the specified key is included in the hash table
// Parameters: HT (pointer to hash table object), key (key)
// Return: the specified key contained in the table returns 1, otherwise 0
// Note: none
int existHashTable( HashTable *ht, int key ) {
	NodeHashTable *n = NULL;

	HASH_FIND_INT( ht, &key, n );

	return n != NULL;
}

// Function: remove the key value pair from the hash table
// Parameters: HT (pointer to hash table object), key (key)
// Return: the key value corresponding to the key
// Note: when the key does not exist, the program will exit in error
int getHashTable( HashTable *ht, int key ) {
	NodeHashTable *n = NULL;

	HASH_FIND_INT( ht, &key, n );
	ERROR_EXIT( n == NULL );

	return n->v;
}

// Function: get the actual used size of hash table
// Parameter: HT (pointer to hash table object)
// Return: the actual used size of the hash table
// Note: none
int sizeHashTable( HashTable *ht ) {
	return HASH_COUNT( ht );
}

// Function: judge whether the hash table is empty
// Parameter: HT (pointer to hash table object)
// Return: returns 1 if it is an empty table, or 0 if it is not
// Note: none
int emptyHashTable( HashTable *ht ) {
	return HASH_COUNT( ht ) < 1;
}

// Function: judge whether the hash table is full
// Parameter: HT (pointer to hash table object)
// Return: 0
// Note: uthash is implemented as chain storage, and its capacity is unlimited in theory
int fullHashTable( HashTable *ht ) {
	return 0;
}

// Function: traverse hash table
// Parameters: HT (pointer to hash table object), func (pointer to user-defined function)
// Return: none
// Note: when func is NULL, exit the program by mistake, and pass the key value pair to func every time during iteration
void traversalHashTable( HashTable *ht, TraversalHashTableFunc *func ) {
	ERROR_EXIT( func == NULL );
	for( NodeHashTable *n = ht; n != NULL; n = n->hh.next ) {
		func( n->k, n->v );
	}
}

// Function: clear hash table
// Parameters: HT (pointer to store hash table object), func (pointer to user-defined function)
// Return: none
// Note: when ht is NULL, exit the program in error. When func is not NULL, pass the key value pair to func before removing each key value pair
void clearHashTable( HashTable **ht, TraversalHashTableFunc *func ) {
	NodeHashTable *c = NULL, *t = NULL;

	ERROR_EXIT( ht == NULL );
	HASH_ITER( hh, *ht, c, t ) {
		HASH_DEL( *ht, c );
		if( func ) {
			func( c->k, c->v );
		}
		free( c );
	}
}

// Function: destroy hash table
// Parameters: HT (pointer to store hash table object), func (pointer to user-defined function)
// Return: none
// Note: when ht is NULL, exit the program in error. When func is not NULL, pass the key value pair to func before removing each key value pair
void delHashTable( HashTable **ht, TraversalHashTableFunc *func ) {
	NodeHashTable *c = NULL, *t = NULL;

	ERROR_EXIT( ht == NULL );
	HASH_ITER( hh, *ht, c, t ) {
		HASH_DEL( *ht, c );
		if( func ) {
			func( c->k, c->v );
		}
		free( c );
	}
}
// Encapsulate the uthash end

int *twoSum( int *nums, int numsSize, int target, int *returnSize ) {
	int *answer = NULL;
	HashTable *ht = newHashTable();

	returnSize[0] = 0;
	answer = malloc( sizeof(*answer) * 2 );
	for( int i = 0; i < numsSize; ++i ) {
		putHashTable( &ht, nums[i], i );
	}
	for( int i = 0; i < numsSize; ++i ) {
		int j = target - nums[i];
		if( existHashTable( ht, j ) && getHashTable( ht, j ) != i ) {
			answer[returnSize[0]++] = i;
			answer[returnSize[0]++] = getHashTable( ht, j );
			break;
		}
	}
	delHashTable( &ht, NULL );

	return answer;
}


Solution 3: use HashTable or HashMap to traverse the process once.
// Package uthash start
#define ERROR_EXIT( expression ) \
if( (expression) ) exit( EXIT_FAILURE )

typedef void ( TraversalHashTableFunc )( int key, int value );

typedef struct NodeHashTable {
	int k;
	int v;
	UT_hash_handle hh;
} NodeHashTable, HashTable;

// Function: create a new hash table
// Parameter: none
// Return: NULL
// Note: the new table in uthash should be NULL initially
HashTable *newHashTable( void ) {
	return NULL;
}

// Function: add key value pair to hash table
// Parameters: HT, key, value
// Return: none
// Note: when ht is NULL, the program will exit in error. When the key exists, the key value will be updated to value
void putHashTable( HashTable **ht, int key, int value ) {
	NodeHashTable *n = NULL;

	ERROR_EXIT( ht == NULL );
	HASH_FIND_INT( *ht, &key, n );
	if( n == NULL ) {
		n = malloc( sizeof(*n) );
		n->k = key;
		HASH_ADD_INT( *ht, k, n );
	}
	n->v = value;
}

// Function: remove the key value pair from the hash table
// Parameters: HT (pointer to store the pointer of hash table object), key (key)
// Return: the removed key value
// Note: when ht is NULL or the key does not exist, the program will exit in error
int removeHashTable( HashTable **ht, int key ) {
	int value = 0;
	NodeHashTable *n = NULL;

	ERROR_EXIT( ht == NULL );
	HASH_FIND_INT( *ht, &key, n );
	ERROR_EXIT( n == NULL );
	HASH_DEL( *ht, n );
	value = n->v;
	free( n );

	return value;
}

// Function: whether the specified key is included in the hash table
// Parameters: HT (pointer to hash table object), key (key)
// Return: the specified key contained in the table returns 1, otherwise 0
// Note: none
int existHashTable( HashTable *ht, int key ) {
	NodeHashTable *n = NULL;

	HASH_FIND_INT( ht, &key, n );

	return n != NULL;
}

// Function: remove the key value pair from the hash table
// Parameters: HT (pointer to hash table object), key (key)
// Return: the key value corresponding to the key
// Note: when the key does not exist, the program will exit in error
int getHashTable( HashTable *ht, int key ) {
	NodeHashTable *n = NULL;

	HASH_FIND_INT( ht, &key, n );
	ERROR_EXIT( n == NULL );

	return n->v;
}

// Function: get the actual used size of hash table
// Parameter: HT (pointer to hash table object)
// Return: the actual used size of the hash table
// Note: none
int sizeHashTable( HashTable *ht ) {
	return HASH_COUNT( ht );
}

// Function: judge whether the hash table is empty
// Parameter: HT (pointer to hash table object)
// Return: returns 1 if it is an empty table, or 0 if it is not
// Note: none
int emptyHashTable( HashTable *ht ) {
	return HASH_COUNT( ht ) < 1;
}

// Function: judge whether the hash table is full
// Parameter: HT (pointer to hash table object)
// Return: 0
// Note: uthash is implemented as chain storage, and its capacity is unlimited in theory
int fullHashTable( HashTable *ht ) {
	return 0;
}

// Function: traverse hash table
// Parameters: HT (pointer to hash table object), func (pointer to user-defined function)
// Return: none
// Note: when func is NULL, exit the program by mistake, and pass the key value pair to func every time during iteration
void traversalHashTable( HashTable *ht, TraversalHashTableFunc *func ) {
	ERROR_EXIT( func == NULL );
	for( NodeHashTable *n = ht; n != NULL; n = n->hh.next ) {
		func( n->k, n->v );
	}
}

// Function: clear hash table
// Parameters: HT (pointer to store hash table object), func (pointer to user-defined function)
// Return: none
// Note: when ht is NULL, exit the program in error. When func is not NULL, pass the key value pair to func before removing each key value pair
void clearHashTable( HashTable **ht, TraversalHashTableFunc *func ) {
	NodeHashTable *c = NULL, *t = NULL;

	ERROR_EXIT( ht == NULL );
	HASH_ITER( hh, *ht, c, t ) {
		HASH_DEL( *ht, c );
		if( func ) {
			func( c->k, c->v );
		}
		free( c );
	}
}

// Function: destroy hash table
// Parameters: HT (pointer to store hash table object), func (pointer to user-defined function)
// Return: none
// Note: when ht is NULL, exit the program in error. When func is not NULL, pass the key value pair to func before removing each key value pair
void delHashTable( HashTable **ht, TraversalHashTableFunc *func ) {
	NodeHashTable *c = NULL, *t = NULL;

	ERROR_EXIT( ht == NULL );
	HASH_ITER( hh, *ht, c, t ) {
		HASH_DEL( *ht, c );
		if( func ) {
			func( c->k, c->v );
		}
		free( c );
	}
}
// Encapsulate the uthash end

int *twoSum( int *nums, int numsSize, int target, int *returnSize ) {
	int *answer = NULL;
	HashTable *ht = newHashTable();

	returnSize[0] = 0;
	answer = malloc( sizeof(*answer) * 2 );
	for( int i = 0; i < numsSize; ++i ) {
		if( existHashTable( ht, target - nums[i] ) ) {
			answer[returnSize[0]++] = getHashTable( ht, target - nums[i] );
			answer[returnSize[0]++] = i;
			break;
		}
		putHashTable( &ht, nums[i], i );
	}
	delHashTable( &ht, NULL );

	return answer;
}



Tags: C network

Posted on Thu, 14 May 2020 10:07:51 -0400 by undecided name 01