두 번호와
제목 설명
정수 배열 nums 및 목표 값 목표를 감안하고, 배열의 두 정수의 목표 값을 식별하고 그 배열 첨자로 돌아 부탁드립니다. 각 입력이 하나의 답에 해당하는 것으로 가정 할 수 있습니다. 그러나 같은 배열 요소를 다시 사용할 수 없습니다.
예
주어의 nums = 2, 7, 11, 15], 목표 = 9 nums가 [0] + nums [1] = 2 + 7 = 9 반환되기 때문에 [0, 1]
방법 | 시간 복잡도 | 우주의 복잡성 | 결과 | 시간 | 기억 |
---|---|---|---|---|---|
방법 | 시간 복잡도 | 우주의 복잡성 | 결과 | 시간 | 기억 |
폭력 열거 | O (N 2 ) | O (1) | 로 | 180ms | 7.6M |
정렬 이중 포인터 + | O (nlog 2 N) | O (n) | 로 | 96ms | 8.4M |
해시 | O (n) | O (n) | 로 | 이 20ms | 15.3M |
자세한 설명
폭력 열거
폭력 아이디어는 매우 간단하다 : [I]의 배열 nums의 nums 탐색의 각 요소를 [I + 1, ..., numsSize 1-] 순회하는 J가 있는지되도록 목표 = nums를 찾는 [내가] + nums [IN J].
int *twoSum(int *nums, int numsSize, int target, int *returnSize)
{
int *retArr = NULL;
int i, j;
for (i = 0; i < numsSize - 1; i++) {
for (j = i + 1; j < numsSize; j++) {
if (nums[i] + nums[j] == target) {
retArr = malloc(sizeof(int) * 2);
assert(retArr != NULL);
retArr[0] = i;
retArr[1] = j;
*returnSize = 2;
return retArr;
}
}
}
*returnSize = 0;
return NULL;
}
정렬 이중 포인터 +
조회 대상이 정렬 된리스트에서 두 수의 합과 같다면, 포인터는 중간에 두에서 열거, 시간 O (N)의 복잡성, 이중 일 수
염두에두고, nums 제 배열은 이중 포인터 후 정렬 될 수 있고 열거하지만, 시간의 종류가 관심을 지불, 우리는 정렬 원래의 배열 인덱스를 가져와야
void qsortWithIndex(int *nums, int *indexArr, int left, int right)
{
int i, j, pivot, pIndex;
if (left >= right) {
return;
}
i = left;
j = right;
pivot = nums[left];
pIndex = indexArr[left];
while (i < j) {
while (i < j && pivot <= nums[j]) {
j--;
}
nums[i] = nums[j];
indexArr[i] = indexArr[j];
while (i < j && pivot >= nums[i]) {
i++;
}
nums[j] = nums[i];
indexArr[j] = indexArr[i];
}
nums[i] = pivot;
indexArr[i] = pIndex;
qsortWithIndex(nums, indexArr, left, i - 1);
qsortWithIndex(nums, indexArr, i + 1, right);
}
int *twoSum(int *nums, int numsSize, int target, int *returnSize)
{
int *indexArr = NULL;
int *retArr = NULL;
int i, j;
indexArr = malloc(sizeof(int) * numsSize);
assert(indexArr != NULL);
for (i = 0; i < numsSize; i++) {
indexArr[i] = i;
}
qsortWithIndex(nums, indexArr, 0, numsSize - 1);
i = 0;
j = numsSize - 1;
while (i < j) {
if (nums[i] + nums[j] == target) {
retArr = malloc(sizeof(int) * 2);
assert(retArr != NULL);
*returnSize = 2;
retArr[0] = indexArr[i];
retArr[1] = indexArr[j];
free(indexArr);
return retArr;
} else if (nums[i] + nums[j] > target) {
j--;
} else {
i++;
}
}
free(indexArr);
*returnSize = 0;
return NULL;
}
해시
이미 질의 요소 값을 저장하고 해당 색인하기 위해 해시 테이블을 이용하여
목표 nums [I] 해시 테이블 요소가 있는지 질의를 배열 nums 통하여 각 소자 nums [I]의
존재한다면 다음, 해당 솔루션이 발견되지하고 있으면 (nums [I], i)는 해쉬 테이블에 삽입
#define MAX_NUMS_SIZE 1000001
typedef struct HashNode {
int index;
int value;
} HashNode;
HashNode node[MAX_NUMS_SIZE];
void hashPut(HashNode **hashTable, HashNode *hashNode)
{
int index;
if (hashNode->value >= 0) {
index = hashNode->value % MAX_NUMS_SIZE;
} else {
index = -1 * hashNode->value % MAX_NUMS_SIZE;
}
while (hashTable[index]) {
index = (index + 1) % MAX_NUMS_SIZE;
}
hashTable[index] = hashNode;
}
HashNode *hashGet(HashNode **hashTable, int value)
{
int index;
if (value >= 0) {
index = value % MAX_NUMS_SIZE;
} else {
index = -1 * value % MAX_NUMS_SIZE;
}
while (hashTable[index]) {
if (hashTable[index]->value != value) {
index = (index + 1) % MAX_NUMS_SIZE;
} else {
return hashTable[index];
}
}
return NULL;
}
int *twoSum(int *nums, int numsSize, int target, int *returnSize)
{
HashNode *hashTable[MAX_NUMS_SIZE] = {NULL};
HashNode *hashNode = NULL;
int *retArr = NULL;
int i;
if (!numsSize || !nums) {
*returnSize = 0;
return NULL;
}
for (i = 0; i < numsSize; i++) {
hashNode = hashGet(hashTable, target - nums[i]);
if (hashNode) {
retArr = malloc(sizeof(int) * 2);
assert(retArr != NULL);
*returnSize = 2;
retArr[0] = hashNode->index;
retArr[1] = i;
return retArr;
}
node[i].index = i;
node[i].value = nums[i];
hashPut(hashTable, &node[i]);
}
*returnSize = 0;
return NULL;
}