zoukankan      html  css  js  c++  java
  • leetcode-1. 两数之和

    leetcode-1. 两数之和。

    给定一个整数数组 nums,和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。

    你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

    示例:

      给定 nums = [2, 7, 11, 15], target = 9,
      因为 nums[0] + nums[1] = 2 + 7 = 9,
      所以返回 [0, 1]。
    

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problemset/all/
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。



    解法一:暴力循环。
    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;
    }
    


    解法二:使用HashTable 或 HashMap,二次遍历过程。
    // 封装 uthash 开始.
    #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;
    
    // 功能: 创建一个新的哈希表.
    // 参数: 无.
    // 返回: NULL.
    // 注意: uthash里的新表应该初始为NULL.
    HashTable *newHashTable( void ) {
    	return NULL;
    }
    
    // 功能: 将键值对加入到哈希表中.
    // 参数: ht(存放哈希表对象的指针的指针), key(键), value(值).
    // 返回: 无.
    // 注意: 当 ht 为NULL 时, 将错误退出程序, 当键存在时,则更新键值为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;
    }
    
    // 功能: 将键值对从哈希表中移除.
    // 参数: ht(存放哈希表对象的指针的指针), key(键).
    // 返回: 被移除的键值.
    // 注意: 当 ht 为NULL 或 键不存在 时, 将错误退出程序.
    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;
    }
    
    // 功能: 哈希表中是否包含了指定键.
    // 参数: ht(哈希表对象的指针), key(键).
    // 返回: 表中包含了指定键返回1, 否则返回0.
    // 注意: 无.
    int existHashTable( HashTable *ht, int key ) {
    	NodeHashTable *n = NULL;
    
    	HASH_FIND_INT( ht, &key, n );
    
    	return n != NULL;
    }
    
    // 功能: 将键值对从哈希表中移除.
    // 参数: ht(哈希表对象的指针), key(键).
    // 返回: 键对应的键值.
    // 注意: 当 键不存在 时, 将错误退出程序.
    int getHashTable( HashTable *ht, int key ) {
    	NodeHashTable *n = NULL;
    
    	HASH_FIND_INT( ht, &key, n );
    	ERROR_EXIT( n == NULL );
    
    	return n->v;
    }
    
    // 功能: 得到哈希表实际已使用大小.
    // 参数: ht(哈希表对象的指针).
    // 返回: 哈希表实际已使用大小.
    // 注意: 无.
    int sizeHashTable( HashTable *ht ) {
    	return HASH_COUNT( ht );
    }
    
    // 功能: 判断是否为空哈希表.
    // 参数: ht(哈希表对象的指针).
    // 返回: 是空表返回1, 否则返回0.
    // 注意: 无.
    int emptyHashTable( HashTable *ht ) {
    	return HASH_COUNT( ht ) < 1;
    }
    
    // 功能: 判断是否为满哈希表.
    // 参数: ht(哈希表对象的指针).
    // 返回: 0.
    // 注意: uthash实现为链式存储,理论上容量是无限制的.
    int fullHashTable( HashTable *ht ) {
    	return 0;
    }
    
    // 功能: 遍历哈希表.
    // 参数: ht(哈希表对象的指针), func(用户自定义函数的指针).
    // 返回: 无.
    // 注意: 当 func 为NULL 时, 将错误退出程序, 在迭代遍历过程中每次都把键值对传给func.
    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 );
    	}
    }
    
    // 功能: 清空哈希表.
    // 参数: ht(存放哈希表对象的指针的指针), func(用户自定义函数的指针).
    // 返回: 无.
    // 注意: 当 ht 为NULL 时, 将错误退出程序, 当 func 不为 NULL 时,在移除每对键值对之前把键值对传给func.
    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 );
    	}
    }
    
    // 功能: 销毁哈希表.
    // 参数: ht(存放哈希表对象的指针的指针), func(用户自定义函数的指针).
    // 返回: 无.
    // 注意: 当 ht 为NULL 时, 将错误退出程序, 当 func 不为 NULL 时,在移除每对键值对之前把键值对传给func.
    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 );
    	}
    }
    // 封装 uthash 结束.
    
    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;
    }
    


    解法三:使用HashTable 或 HashMap,一次遍历过程。
    // 封装 uthash 开始.
    #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;
    
    // 功能: 创建一个新的哈希表.
    // 参数: 无.
    // 返回: NULL.
    // 注意: uthash里的新表应该初始为NULL.
    HashTable *newHashTable( void ) {
    	return NULL;
    }
    
    // 功能: 将键值对加入到哈希表中.
    // 参数: ht(存放哈希表对象的指针的指针), key(键), value(值).
    // 返回: 无.
    // 注意: 当 ht 为NULL 时, 将错误退出程序, 当键存在时,则更新键值为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;
    }
    
    // 功能: 将键值对从哈希表中移除.
    // 参数: ht(存放哈希表对象的指针的指针), key(键).
    // 返回: 被移除的键值.
    // 注意: 当 ht 为NULL 或 键不存在 时, 将错误退出程序.
    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;
    }
    
    // 功能: 哈希表中是否包含了指定键.
    // 参数: ht(哈希表对象的指针), key(键).
    // 返回: 表中包含了指定键返回1, 否则返回0.
    // 注意: 无.
    int existHashTable( HashTable *ht, int key ) {
    	NodeHashTable *n = NULL;
    
    	HASH_FIND_INT( ht, &key, n );
    
    	return n != NULL;
    }
    
    // 功能: 将键值对从哈希表中移除.
    // 参数: ht(哈希表对象的指针), key(键).
    // 返回: 键对应的键值.
    // 注意: 当 键不存在 时, 将错误退出程序.
    int getHashTable( HashTable *ht, int key ) {
    	NodeHashTable *n = NULL;
    
    	HASH_FIND_INT( ht, &key, n );
    	ERROR_EXIT( n == NULL );
    
    	return n->v;
    }
    
    // 功能: 得到哈希表实际已使用大小.
    // 参数: ht(哈希表对象的指针).
    // 返回: 哈希表实际已使用大小.
    // 注意: 无.
    int sizeHashTable( HashTable *ht ) {
    	return HASH_COUNT( ht );
    }
    
    // 功能: 判断是否为空哈希表.
    // 参数: ht(哈希表对象的指针).
    // 返回: 是空表返回1, 否则返回0.
    // 注意: 无.
    int emptyHashTable( HashTable *ht ) {
    	return HASH_COUNT( ht ) < 1;
    }
    
    // 功能: 判断是否为满哈希表.
    // 参数: ht(哈希表对象的指针).
    // 返回: 0.
    // 注意: uthash实现为链式存储,理论上容量是无限制的.
    int fullHashTable( HashTable *ht ) {
    	return 0;
    }
    
    // 功能: 遍历哈希表.
    // 参数: ht(哈希表对象的指针), func(用户自定义函数的指针).
    // 返回: 无.
    // 注意: 当 func 为NULL 时, 将错误退出程序, 在迭代遍历过程中每次都把键值对传给func.
    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 );
    	}
    }
    
    // 功能: 清空哈希表.
    // 参数: ht(存放哈希表对象的指针的指针), func(用户自定义函数的指针).
    // 返回: 无.
    // 注意: 当 ht 为NULL 时, 将错误退出程序, 当 func 不为 NULL 时,在移除每对键值对之前把键值对传给func.
    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 );
    	}
    }
    
    // 功能: 销毁哈希表.
    // 参数: ht(存放哈希表对象的指针的指针), func(用户自定义函数的指针).
    // 返回: 无.
    // 注意: 当 ht 为NULL 时, 将错误退出程序, 当 func 不为 NULL 时,在移除每对键值对之前把键值对传给func.
    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 );
    	}
    }
    // 封装 uthash 结束.
    
    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;
    }
    



  • 相关阅读:
    0401-服务注册与发现、Eureka简介
    001-OSI七层模型,TCP/IP五层模型
    云原生应用开发12-Factors
    0301-服务提供者与服务消费者
    0201-开始使用Spring Cloud实战微服务准备工作
    0107-将Monolith重构为微服务
    0106-选择微服务部署策略
    0105-微服务的事件驱动的数据管理
    0104-微服务体系结构中的服务发现
    0103-微服务架构中的进程间通信
  • 原文地址:https://www.cnblogs.com/hujunxiang98/p/12841148.html
Copyright © 2011-2022 走看看