Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

หาจำนวนซับอาร์เรย์ที่มีผลรวมอยู่ในช่วงที่กำหนดด้วย C++

ในบทความนี้ เราจะแก้ปัญหาการหาจำนวนซับอาร์เรย์ที่มีผลรวมอยู่ในช่วงที่กำหนด โดยใช้โปรแกรม C++ โจทย์ให้มาอาร์เรย์ arr[] ของจำนวนเต็มบวก และช่วง {L, R} เราต้องคำนวณจำนวนซับอาร์เรย์ทั้งหมดที่มีผลรวมอยู่ในช่วง L ถึง R ตัวอย่างดังนี้:

Input : arr[] = {1, 4, 6}, L = 3, R = 8 Output : 3 ซับอาร์เรย์คือ {1, 4}, {4}, {6}
Input : arr[] = {2, 3, 5, 8}, L = 4, R = 13 Output : 6 ซับอาร์เรย์คือ {2, 3}, {2, 3, 5}, {3, 5}, {5}, {5, 8}, {8}

วิธีการแก้ปัญหา

เราจะอธิบายสองวิธีในการแก้ปัญหานี้ด้วย C++:

1. วิธี Brute Force

วิธีพื้นฐานที่สุดคือ คำนวณผลรวมของซับอาร์เรย์ทุกชุด แล้วตรวจสอบว่าผลรวมนั้นอยู่ในช่วงที่กำหนดหรือไม่ (แต่วิธีนี้ใช้เวลามาก เพราะความซับซ้อนด้านเวลาคือ O(n²) โดย n คือขนาดอาร์เรย์)

2. วิธีที่มีประสิทธิภาพ (Efficient Approach - Sliding Window)

เพื่อประหยัดเวลา เราใช้วิธีที่เรียกว่า Efficient Approach ซึ่งใช้เทคนิค Sliding Window ช่วยให้คำนวณผลลัพธ์ได้เร็วขึ้นใน O(n)

ตัวอย่างโค้ด

#include <bits/stdc++.h>
using namespace std;

int subCount(int *arr, int n, int x) {
    int start = 0, end = 0, sum = 0, count = 0;
    while (end < n) { // เลื่อนขอบขวาในลูปนี้
        sum = sum + arr[end];
        while(start <= end && sum >= x) { // ลูปนี้เลื่อนขอบซ้าย
            sum = sum - arr[start]; // ลดผลรวมขณะเลื่อนขอบซ้าย
            start++; // เลื่อนขอบซ้าย
        }
        count = count + ((end - start) + 1); // นับซับอาร์เรย์
        end++;
    }
    return count;
}

int main() {
    int n; // ขนาดอาร์เรย์
    int L, R;
    cin >> n;
    int arr[n];
    for(int i = 0; i < n; i++)
        cin >> arr[i];
    cin >> L >> R;
    int answer;
    answer = subCount(arr, n, R) - subCount(arr, n, (L - 1)); // คำตอบสุดท้าย
    cout << answer << "\n";
    return 0;
}

ผลลัพธ์

1

คำอธิบายโค้ด

ในวิธีนี้ เรานับจำนวนซับอาร์เรย์ที่มีผลรวมน้อยกว่าขีดจำกัดบน (R) ของช่วงที่กำหนด แล้วลบด้วยจำนวนซับอาร์เรย์ที่มีผลรวมน้อยกว่าขีดจำกัดล่าง (L-1) โดยใช้ฟังก์ชัน subCount

ฟังก์ชัน subCount

ฟังก์ชันนี้ใช้เทคนิค Sliding Window เพื่อหาจำนวนซับอาร์เรย์ที่มีผลรวมน้อยกว่า x

เริ่มต้นให้ 'end' และ 'start' เท่ากับ 0 เมื่อเดินทางผ่านอาร์เรย์ เราจะรักษาผลรวมของสมาชิกจาก start ถึง end หลังจากนั้น หาก start เท่ากับ end และผลรวมมากกว่าหรือเท่ากับ x เราจะเริ่มเลื่อน start และลดผลรวมลง (เพราะนำสมาชิกออกจากผลรวม) จนกว่าผลรวมจะน้อยกว่า x หรือ start จะมากกว่า end ตอนนี้เราเพิ่มจำนวนซับอาร์เรย์เข้าไปใน count แล้วเพิ่มขอบขวา 1 เมื่อลูปภายนอกสิ้นสุด เราจะคืนค่าจำนวนซับอาร์เรย์ทั้งหมด

สรุป

ในบทความนี้ เราแก้ปัญหาการหาจำนวนซับอาร์เรย์ที่มีผลรวมอยู่ในช่วงที่กำหนด ด้วยความซับซ้อนด้านเวลา O(n) โดยใช้เทคนิค Sliding Window เรายังเรียนรู้โปรแกรม C++ สำหรับปัญหานี้ และวิธีการแก้ปัญหาทั้งแบบปกติและแบบมีประสิทธิภาพ สามารถเขียนโปรแกรมเดียวกันในภาษาอื่นๆ เช่น C, Java, Python ได้เช่นกัน