সরাসরি প্রধান সামগ্রীতে চলে যান

নেক্সট গ্রেটার এলিমেন্ট II: সার্কুলার অ্যারে এবং স্ট্যাকের জাদু

আজকের ক্লাসে আমরা ডেটা স্ট্রাকচার এবং অ্যালগরিদমের (DSA) একটি খুব জনপ্রিয় এবং গুরুত্বপূর্ণ সমস্যা নিয়ে আলোচনা করব, যার নাম Next Greater Element II। এটি লিটকোডের (LeetCode) ৫০০ নম্বর সমস্যা। যারা ইতিমধ্যে সাধারণ "Next Greater Element" সমাধান করেছেন, তাদের জন্য এটি বোঝা আরও সহজ হবে। মূলত একটি সাধারণ অ্যারেকে কীভাবে সার্কুলার বা বৃত্তাকার উপায়ে চিন্তা করে বড় সংখ্যা খুঁজে বের করা যায়, তা-ই এখানে শিখব।


১. সার্কুলার অ্যারে এবং সমস্যার মূল ধারণা (Introduction)

সাধারণত একটি অ্যারেতে আমরা বাম থেকে ডানে সংখ্যা খুঁজি। কিন্তু সার্কুলার অ্যারে (Circular Array) মানে হলো, অ্যারের শেষ এলিমেন্টটির পর আবার প্রথম এলিমেন্টটি শুরু হবে। অনেকটা ঘড়ির কাঁটার মতো!

ভিডিও রেফারেন্স: L73. Next Greater Element - II | Stack & Queue

উদাহরণ: ধরুন আমাদের কাছে একটি অ্যারে আছে: [1, 2, 1]

  • 1-এর জন্য পরের বড় সংখ্যা হলো 2 [01:48]।

  • 2-এর জন্য ডানে কোনো বড় সংখ্যা নেই। কিন্তু যেহেতু এটা সার্কুলার, তাই আমরা আবার শুরুতে ফিরে গিয়ে দেখব। শুরুতে আছে 1, যা 2-এর চেয়ে বড় নয়। তাই এর উত্তর হবে -1

  • শেষ 1-এর জন্য ডানে কিছু নেই, কিন্তু শুরুতে ফিরে গেলে আমরা 2 পাই, যা 1-এর চেয়ে বড়। তাই উত্তর হবে 2 [02:13]।


২. সমাধানের বুদ্ধি: ডাবল অ্যারে না বানিয়েও সমাধান (Optimized Approach)

সবচেয়ে সহজ উপায় হতে পারত অ্যারেকে দুইবার লিখে ফেলা (যেমন [1, 2, 1, 1, 2, 1])। কিন্তু এতে মেমোরি বেশি খরচ হয়। এর বদলে আমরা একটি মজার ট্রিক ব্যবহার করব—আমরা লুপ চালাব 2 * n বার এবং ইনডেক্স ঠিক রাখতে Modulo (%) অপারেটর ব্যবহার করব [10:01]।

সহজ কথায় ব্যাখ্যা:

  • Modulo (%): এটি ভাগশেষ বের করার একটি উপায়। ধরুন অ্যারের সাইজ ৫। আপনি যদি ৬ নম্বর ইনডেক্স খোঁজেন, তবে 6 % 5 = 1 হবে। অর্থাৎ এটি আপনাকে আবার ঘুরিয়ে ১ নম্বর ইনডেক্সে নিয়ে আসবে। একেই বলে সার্কুলার নেভিগেশন।

আমরা এখানে স্ট্যাক (Stack) ব্যবহার করব। স্ট্যাকে আমরা সংখ্যার ইনডেক্স জমা রাখব এবং পিছন দিক থেকে লুপ চালানো শুরু করব যাতে ডানদিকের বড় সংখ্যাগুলো সহজেই ট্র্যাক করা যায় [07:36]।


৩. কোডিং সমাধান (Coding Implementation)

নিচে সহজভাবে জাভাস্ক্রিপ্ট/সি++ স্টাইলে কোডটি দেওয়া হলো:

C++

vector<int> nextGreaterElements(vector<int>& nums) {
    int n = nums.size();
    vector<int> res(n, -1); // শুরুতে সবগুলোকে -1 ধরে নিলাম
    stack<int> s;

    // আমরা লুপ চালাব ২ বার (2*n-1 থেকে শুরু করে ০ পর্যন্ত)
    for (int i = 2 * n - 1; i >= 0; i--) {
        // যতক্ষণ স্ট্যাকের উপরের সংখ্যাটি বর্তমান সংখ্যার চেয়ে ছোট বা সমান
        while (!s.empty() && nums[s.top()] <= nums[i % n]) {
            s.pop(); // ছোট সংখ্যাগুলোকে সরিয়ে দাও [00:15:20]
        }
        
        // যদি i আমাদের আসল অ্যারের রেঞ্জে থাকে (i < n)
        if (i < n) {
            if (!s.empty()) {
                res[i] = nums[s.top()]; // স্ট্যাকের টপ-ই হলো পরের বড় সংখ্যা
            }
        }
        
        // বর্তমান ইনডেক্সটি স্ট্যাকে রাখছি
        s.push(i % n); [00:18:43]
    }
    return res;
} 

কোডের ব্যাখ্যা:

  • 2 * n - 1 থেকে লুপ: এর মানে হলো আমরা অ্যারেকে দুইবার মনে মনে কল্পনা করছি। প্রথমবার স্ট্যাক তৈরি করার জন্য এবং দ্বিতীয়বার আসল উত্তর পাওয়ার জন্য।

  • s.pop(): যদি আমরা এমন কোনো সংখ্যা পাই যা বর্তমান সংখ্যার চেয়ে ছোট, তবে সে আমাদের কোনো কাজে আসবে না, তাই তাকে বের করে দিচ্ছি। কারণ আমরা "বড়" সংখ্যা খুঁজছি।

  • i % n: এটি নিশ্চিত করে যে আমরা সবসময় অ্যারের সীমার মধ্যেই থাকব [10:07]।


৪. কঠিন শব্দের সহজ মানে (Glossary)

  • Stack (স্ট্যাক): এটি একটি ডেটা স্ট্রাকচার যেখানে শেষ ঢোকানো জিনিসটি আগে বের হয় (LIFO - Last In First Out)। যেমন একটার ওপর একটা প্লেট সাজিয়ে রাখা।

  • Dry Run (ড্রাই রান): কোড লেখার আগে খাতা-কলমে পরীক্ষা করে দেখা যে সেটি কীভাবে কাজ করবে [03:19]।

  • Time Complexity (টাইম কমপ্লেক্সিটি): একটি কোড কত দ্রুত চলে। এখানে এর মান O(n), কারণ আমরা প্রতিটা এলিমেন্টকে সর্বোচ্চ দুইবার দেখছি [19:30]।


৫. আমার বিশ্লেষণ ও মতামত (Final Analysis & Suggestions)

সারাংশ: কন্টেন্ট ক্রিয়েটর (শ্রদ্ধা খাপরা) এখানে বোঝাতে চেয়েছেন যে, সার্কুলার অ্যারের সমস্যা দেখে ভয় পাওয়ার কিছু নেই। আপনি যদি লুপের সীমানা বাড়িয়ে দেন এবং মডুলো ব্যবহার করেন, তবে এটি একটি সাধারণ লিনিয়ার অ্যারে সমস্যার মতোই সমাধান করা সম্ভব।

বাস্তব জীবনের সাথে মিল: এই অ্যালগরিদমটি অনেকটা স্টোক মার্কেট বা তাপমাত্রার ওঠানামা বিশ্লেষণের মতো। যেমন, আজকের চেয়ে বেশি গরম কবে পড়বে তা জানার জন্য আমরা সামনের দিনগুলো দেখি। যদি শীতকাল শেষ হয়ে যায়, আমরা আবার আগামী বছরের গরমকালের ডেটা দেখি।

বিকল্প বুদ্ধি: যদি স্ট্যাক ব্যবহার করতে কঠিন লাগে, তবে সাধারণ দুইবার লুপ চালিয়ে (Brute Force) করা যায়, কিন্তু সেটি বড় ডেটার ক্ষেত্রে অনেক ধীর হয়ে যাবে (O(n2))। তাই ইন্টারভিউতে সবসময় এই স্ট্যাক বা O(n) পদ্ধতি ব্যবহার করাই বুদ্ধিমানের কাজ [03:13]।

পরামর্শ: যারা নতুন শিখছেন, তারা প্রথমে সাধারণ "Next Greater Element I" সমাধান করুন। এরপর এই সার্কুলার ভার্সনটি ট্রাই করুন। স্ট্যাকের ধারণা পরিষ্কার থাকলে এটি পানির মতো সহজ মনে হবে!

[

L73. Next Greater Element - II | Stack & Queue

Shradha Khapra · 42K views

](http://www.youtube.com/watch?v=If--3pm9K3U)

মন্তব্যসমূহ

এই ব্লগটি থেকে জনপ্রিয় পোস্টগুলি

সিজ্জিন (Sijjin) vs ইল্লিয়িন (Illiyin) পার্থক্য Difference

Sijjin (سِجِّين) এবং Illiyin (عِلِّيِّين) —এ দুটি শব্দ কুরআনে এসেছে এবং দুটোই মানুষের আমলনামা সংরক্ষণ সম্পর্কিত স্থানকে নির্দেশ করে। ১. সিজ্জিন (Sijjin) সিজ্জিন হলো পাপীদের (কাফের, মুনাফিক ও দুরাচারীদের) আমলনামা সংরক্ষণের স্থান। এটি সাত তলদেশের নীচে এক কারাগার বা অন্ধকার জগতে অবস্থিত বলে উল্লেখ রয়েছে। সূরা আল-মুতাফফিফীন (৮৩:৭-৯) তে বলা হয়েছে: "كَلَّا إِنَّ كِتَابَ الْفُجَّارِ لَفِي سِجِّينٍ ۝ وَمَا أَدْرَاكَ مَا سِجِّينٌ ۝ كِتَابٌ مَرْقُومٌ" অর্থ: "না, পাপীদের আমলনামা সিজ্জিনে সংরক্ষিত। তুমি কি জানো, সিজ্জিন কী? এটি এক লিখিত দলিল।" সিজ্জিনকে একটি কারাগার, সংকীর্ণ স্থান, বা নিচের স্তরে অবস্থিত এক অন্ধকার দুনিয়া হিসেবে ব্যাখ্যা করা হয়। ২. ইল্লিয়িন (Illiyin) ইল্লিয়িন হলো সৎকর্মশীলদের (মুমিন ও নেককারদের) আমলনামা সংরক্ষণের স্থান । এটি সপ্তম আসমানের ওপরে সংরক্ষিত এক সম্মানিত স্থান। সূরা আল-মুতাফফিফীন (৮৩:১৮-২১) তে বলা হয়েছে: "كَلَّا إِنَّ كِتَابَ الْأَبْرَارِ لَفِي عِلِّيِّينَ ۝ وَمَا أَدْرَاكَ مَا عِلِّيُّونَ ۝ كِتَابٌ مَرْقُومٌ ۝ يَش...

জাভা ফিডব্যাক এবং স্ট্রাকচার্ড কনকারেন্সি: বিবর্তনের গল্প

Introduction এই ভিডিওর নির্দিষ্ট অংশে জাভা ল্যাঙ্গুয়েজ আর্কিটেক্ট ব্রায়ান গোয়েটজ (Brian Goetz) আলোচনা করেছেন কীভাবে জাভার নতুন ফিচারগুলো তৈরি হয় এবং এতে সাধারণ ডেভেলপারদের মতামতের গুরুত্ব কতটুকু। বিশেষ করে Structured Concurrency -এর মতো জটিল ফিচারগুলো কেন বারবার 'Preview' অবস্থায় থাকে এবং কীভাবে কমিউনিটির ফিডব্যাক সেই ফিচারগুলোকে আরও নিখুঁত করতে সাহায্য করে, তা এখানে সহজভাবে বোঝানো হয়েছে। ১. ভালো ফিডব্যাক আসলে কী? ভিডিও রেফারেন্স: [ 34:53 ] ব্রায়ান গোয়েটজ বলছেন যে, জাভা টিম যখন কোনো নতুন ফিচারের খসড়া (Draft) বা প্রস্তাব (JEP) প্রকাশ করে, তখন তারা এমন কিছু জানতে চায় যা তারা নিজেরা আগে ভাবেনি। বিস্তারিত: একজন ডেভেলপার হিসেবে আমরা যখন কোনো নতুন ফিচার দেখি, আমাদের প্রথম প্রতিক্রিয়া হয় সেটার Syntax বা লেখার ধরন নিয়ে। কিন্তু ব্রায়ানের মতে, "এই লেখাটা কেন এমন হলো?" বা "এটা কোটলিন বা স্কালা-র মতো কেন নয়?"—এই ধরনের ফিডব্যাক খুব একটা কাজে আসে না। আসল দামী ফিডব্যাক হলো সেইটা, যা নতুন কোনো বাস্তব সমস্যা (Edge Case) তুলে ধরে। আমার চিন্তা: আপনি যদি কেবল দ...

[Master Post] Machine Learning for Everybody – Full Course

URL: https://youtu.be/i_LwzRVP7bg?t=0 Title: Machine Learning for Everybody – Full Course Topics:- মেশিন লার্নিংয়ের হাতেখড়ি এবং গুগল কোল্যাব সেটআপ মেশিন লার্নিংয়ের খুঁটিনাটি ও ফিচারের সহজ পাঠ Classification বনাম Regression এবং মডেল ট্রেনিংয়ের সহজ পাঠ মেশিন লার্নিংয়ের জন্য ডেটা তৈরি এবং প্রসেসিং করার সহজ গাইড K-Nearest Neighbors (KNN) থিওরির সহজ পাঠ কে-নিয়ারেস্ট নেইবারস (KNN) ইমপ্লিমেন্টেশন সহজ বাংলায় নেইভ বেইজ থিওরি এবং এর প্রয়োগ: সহজ পাঠ লজিস্টিক রিগ্রেশন: থিওরি ও ইমপ্লিমেন্টেশন SVM থিওরি এবং ইমপ্লিমেন্টেশন সহজ পাঠ নিউরাল নেটওয়ার্ক এবং টেনসরফ্লোর সহজ পাঠ টেনসরফ্লো দিয়ে নিউরাল নেটওয়ার্ক ক্লাসিফিকেশন শেখার সহজ গাইড লিনিয়ার রিগ্রেশন: সহজ কথায় মূল ধারণা ও গণিত লিনিয়ার রিগ্রেশন: সহজ ভাষায় খুঁটিনাটি ও হাতে-কলমে শেখা লিনিয়ার রিগ্রেশন এবং নিউরন মডেলের সহজ পাঠ TensorFlow দিয়ে রিগ্রেশন নিউরাল নেটওয়ার্ক তৈরি - পার্ট ১ টেনসরফ্লো দিয়ে রিগ্রেশন নিউরাল নেটওয়ার্ক তৈরি - পার্ট ২ আনসুপারভাইজড লার্নিং: কে-মিনস ক্লাস্টারিংয়ের সহজ পাঠ Principal C...