给定4个数字组合的C语言算法,leetcode 454. 四数相加 II c语言
如題:
給定四個(gè)包含整數(shù)的數(shù)組列表?A , B , C , D ,計(jì)算有多少個(gè)元組 (i, j, k, l)?,使得?A[i] + B[j] + C[k] + D[l] = 0。
為了使問(wèn)題簡(jiǎn)單化,所有的 A, B, C, D 具有相同的長(zhǎng)度?N,且 0 ≤ N ≤ 500 。所有整數(shù)的范圍在 -228 到 228 - 1 之間,最終
結(jié)果不會(huì)超過(guò)?231 - 1 。
例如:
輸入:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]
輸出:
2
解釋:
兩個(gè)元組如下:
1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0
這道題在hash專項(xiàng)練習(xí)里遇到,最初的方法是循環(huán)法(俗稱暴力),遍歷4個(gè)數(shù)組,計(jì)算每種組合,時(shí)間復(fù)雜度在O(n^4)。復(fù)雜度還蠻大的,應(yīng)該可以優(yōu)化,想了半天,沒(méi)想到啥巧妙的方法。看了其它人的題解,可以優(yōu)化到O(n^2),思路:遍歷AB數(shù)組,計(jì)算每種組合的和,將和放入到hash桶中,key為和,值為次數(shù)。時(shí)間復(fù)雜度為O(n^2)。接著遍歷CD數(shù)組,計(jì)算各種組合s,查找hash中是否存在-s,找到則累積可能性。時(shí)間復(fù)雜度為O(n^2)。總的時(shí)間復(fù)雜度為O(2n^2)。和O(n^4)相比,的確優(yōu)化了不少。hash需要占空間,空間換時(shí)間,不虧。思路倒是很簡(jiǎn)單,但是的確是沒(méi)想到,其實(shí)就是減少內(nèi)層循環(huán)的次數(shù)。遇到同樣的題型都可以如此優(yōu)化。有學(xué)會(huì)一招。下面是是c語(yǔ)言的解法:
/*
* 解法1:暴力遍歷,O(n^4)
* 解法2:使用hash優(yōu)化暴力算法,O(n^2)
*/
typedef struct hlist {
int nkey, pkey;
int nNum, pNum;
struct hlist *next;
}*hnode;
hnode newHashNode(int key)
{
hnode n = (hnode)calloc(1, sizeof(struct hlist));
if (key < 0){
n->nkey = key;
n->pkey = 0 - key;
n->nNum = 1;
}else{
n->pkey = key;
n->nkey = 0 - key;
n->pNum = 1;
if (key == 0)
n->nNum = 1;
}
return n;
}
int hashKey(int s)
{
if (s < 0)
return (0 - s) % 10000;
else
return s % 10000;
}
int fourSumCount(int* A, int ASize, int* B, int BSize, int* C, int CSize, int* D, int DSize){
int i,j,n = 0,s, key;
hnode hash[10000] = {0}, prev, curr, new;
//特殊情況處理
if (ASize == 0 || BSize == 0 ||CSize == 0 || DSize == 0)
return 0;
//遍歷AB和,將其加入到hash桶中,和為key,值為次數(shù)
for (i = 0; i < ASize; i++)
{
for (j = 0; j < BSize; j++)
{
s = A[i] + B[j];
key = hashKey(s);
prev = NULL;
curr = hash[key];
while (curr)
{
if (curr->nkey == s)
{
curr->nNum++;
break;
}
else if (curr->pkey == s)
{
curr->pNum++;
break;
}
else
{
prev = curr;
curr = curr->next;
}
}
if (!curr)
{
new = newHashNode(s);
if (prev)
prev->next = new;
else
hash[key] = new;
}
}
}
//遍歷CD和s,在hash表中查找-s,統(tǒng)計(jì)次數(shù)。
for (i = 0; i < CSize; i++)
{
for (j = 0; j < DSize; j++)
{
s = C[i] + D[j];
s = 0 - s;
key = hashKey(s);
curr = hash[key];
while (curr)
{
if (curr->nkey == s){
n += curr->nNum;
break;
}
else if (curr->pkey == s){
n += curr->pNum;
break;
}
else
curr = curr->next;
}
}
}
return n;
}
=============================================================================================
Linux應(yīng)用程序、內(nèi)核、驅(qū)動(dòng)開(kāi)發(fā)交流討論群(745510310),對(duì)后端、互聯(lián)網(wǎng)感興趣的同學(xué)可以加群討論、交流、資料查找等,前進(jìn)的道路上,你不是一個(gè)人奧^_^。
---------------------
版權(quán)聲明:本文為CSDN博主「mrsonko」的原創(chuàng)文章,遵循CC 4.0 by-sa版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/fuyuande/article/details/99434278
總結(jié)
以上是生活随笔為你收集整理的给定4个数字组合的C语言算法,leetcode 454. 四数相加 II c语言的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java设置行显示复选框_java sp
- 下一篇: 不到30的成本,还不赶紧造起来——盘点软