สมมติว่าเราได้ให้อาร์เรย์ของจำนวนเต็ม N ที่มีหน้าที่ค้นหาความยาวของอาร์เรย์ย่อยที่มีความยาวสูงสุด หากไม่มีอาร์เรย์ย่อยใดๆ ที่มีความยาวสูงสุดหรือผลรวมเท่ากับ 0 ให้คืนค่า '0' ตัวอย่างเช่น
อินพุต-1 −
N = 8
A[ ] = {15, -5, -1, 5,1, 4 } ผลผลิต −
4
คำอธิบาย − อาร์เรย์ย่อยที่ใหญ่ที่สุดที่มีค่าผลรวมเป็นศูนย์คือ { -5, -1, 5, 1} ซึ่งมีความยาวเท่ากับ 4
อินพุต-2 −
N = 5
A[ ] = {3, 2 ,4, 8, -1} ผลผลิต −
0
คำอธิบาย − เนื่องจากไม่มีอาร์เรย์ย่อยที่มีผลรวมเท่ากับศูนย์ เอาต์พุตจึงเป็น '0'
แนวทางการแก้ปัญหานี้
มีหลายวิธีในการแก้ปัญหานี้โดยเฉพาะ อัลกอริทึมที่เหมาะสมที่สุดในการแก้ปัญหาในเวลาเชิงเส้น O(n) คือการใช้ตารางแฮช
แนวคิดคือการสร้างตารางแฮชที่เก็บผลรวมของอาร์เรย์ย่อยทั้งหมดที่มีการจัดเก็บผลรวมเป็นคีย์และดัชนีเป็นค่า
ก่อนอื่นเราจะสำรวจทั้งอาร์เรย์และเก็บผลรวมปัจจุบัน เราจะตรวจสอบว่าผลรวมปัจจุบันมีอยู่ในตารางแฮชหรือไม่ หากมีอยู่ในตารางแฮช ให้อัปเดตความยาวสูงสุดของอาร์เรย์ย่อย
-
รับอินพุตขนาด N ของอาร์เรย์
-
ฟังก์ชัน lenMax(int *arr, int size) รับอาร์เรย์และขนาดของอาร์เรย์เป็นอินพุต ซึ่งจะคืนค่าความยาวสูงสุดของอาร์เรย์ย่อยที่มีผลรวมเป็นศูนย์
-
แผนที่แบบไม่เรียงลำดับของจำนวนเต็มที่มีคีย์เป็นผลรวมและค่าในขณะที่ดัชนีตรวจสอบว่าผลรวมใด ๆ เกิดขึ้นซ้ำหรือไม่
-
วนซ้ำองค์ประกอบอาร์เรย์และค้นหาผลรวมปัจจุบันของอาร์เรย์หากผลรวมมีอยู่ใน hashtable จากนั้นให้หาความยาวสูงสุดของอาร์เรย์ย่อย หากไม่เป็นเช่นนั้น ให้แทรกผลรวมใหม่และดัชนีลงในตารางแฮชเทเบิล
-
คืนค่าความยาวสูงสุดเป็นผลลัพธ์
ตัวอย่าง
#include<bits/stdc++.h>
using namespace std;
int lenMax(int *arr, int size){
unordered_map<int,int>mp;
int sum=0;
int maxlen=0;
for(int i=0;i<size;i++){
sum+=arr[i];
if(arr[i]==0 && maxlen==0){
maxlen=1;
}
if(sum==0){
maxlen=i+1;
}
if(mp.find(sum)!= mp.end()){
maxlen= max(maxlen, i-mp[sum]);
} else {
mp[sum]=i;
}
}
return maxlen;
}
int main(){
int N=6;
int A[N]={15,-2,2,-8,1,7,10,23};
cout<<lenMax(A,N)<<endl;
return 0;
} ผลลัพธ์
หากเราจะเรียกใช้โค้ดข้างต้น มันจะพิมพ์ผลลัพธ์เป็น,
5
อาร์เรย์ย่อยที่ใหญ่ที่สุดที่มีผลรวม=0 คือ {-2, 2, -8, 1, 7} ดังนั้น ความยาวของอาร์เรย์ย่อยที่ใหญ่ที่สุดคือ '5'