Live Coding

जाँचें कि क्या कोई ऑब्जेक्ट खाली है

यह कैसे जांचें कि कोई JavaScript ऑब्जेक्ट खाली है?

स्पष्टीकरण: एक ऑब्जेक्ट खाली होता है यदि उसमें कोई खुद की गणनीय प्रॉपर्टी नहीं होती है। हम Object.keys(obj) का उपयोग कर सकते हैं जो दिए गए ऑब्जेक्ट की खुद की गणनीय प्रॉपर्टी नामों के साथ एक सरणी लौटाता है। यदि इस सरणी की लंबाई 0 है, तो ऑब्जेक्ट खाली है।

function isEmpty(obj) { return Object.keys(obj).length === 0; } console.log(isEmpty({})); // true console.log(isEmpty({ a: 1 })); // false

एक स्ट्रिंग को उलटना

दी गई स्ट्रिंग को उलटने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: सबसे सीधा तरीका है स्ट्रिंग को वर्णों की सरणी में बदलना, सरणियों के लिए अंतर्निहित reverse() विधि का उपयोग करना, और फिर वर्णों को वापस एक स्ट्रिंग में जोड़ना।

function reverseString(str) { return str.split('').reverse().join(''); } console.log(reverseString('hello')); // 'olleh'

पैलिंड्रोम जाँच

एक फ़ंक्शन लिखें जो जांचता है कि दी गई स्ट्रिंग एक पैलिंड्रोम है या नहीं।

स्पष्टीकरण: एक पैलिंड्रोम एक शब्द या वाक्यांश होता है जिसे आगे और पीछे दोनों तरफ से पढ़ने पर एक जैसा लगता है। हम स्ट्रिंग को उलटकर (अधिक मज़बूत जाँच के लिए केस और गैर-अल्फ़ान्यूमेरिक वर्णों को अनदेखा करते हुए, लेकिन यहाँ हम एक साधारण जाँच कर रहे हैं) और मूल से इसकी तुलना करके इसकी जाँच कर सकते हैं।

function isPalindrome(str) { const reversed = str.split('').reverse().join(''); return str === reversed; } console.log(isPalindrome('racecar')); // true console.log(isPalindrome('hello')); // false

एक सरणी में अधिकतम संख्या ज्ञात करें

संख्याओं की सरणी में सबसे बड़ी संख्या ज्ञात करने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: आप सरणी के माध्यम से पुनरावृति कर सकते हैं, अब तक मिली सबसे बड़ी संख्या का ट्रैक रख सकते हैं। वैकल्पिक रूप से, आप सरणी तत्वों को तर्क के रूप में पास करने के लिए स्प्रेड सिंटैक्स (...) के साथ Math.max() फ़ंक्शन का उपयोग कर सकते हैं।

function findMaxNumber(arr) { if (arr.length === 0) return undefined; // या त्रुटि फेंकें return Math.max(...arr); } console.log(findMaxNumber([1, 5, 2, 9, 3])); // 9

फ़िज़बज़

एक ऐसा प्रोग्राम लिखें जो 1 से n तक की संख्याएँ प्रिंट करे। लेकिन तीन के गुणकों के लिए, संख्या के बजाय 'Fizz' प्रिंट करें, और पाँच के गुणकों के लिए, 'Buzz' प्रिंट करें। उन संख्याओं के लिए जो तीन और पाँच दोनों के गुणक हैं, 'FizzBuzz' प्रिंट करें।

स्पष्टीकरण: यह क्लासिक समस्या लूप और कंडीशनल के मूल तर्क का मूल्यांकन करती है। आपको 1 से n तक पुनरावृति करने और 3 और 5 से विभाज्यता की जाँच के लिए मॉड्यूलो ऑपरेटर (%) का उपयोग करने की आवश्यकता है।

function fizzBuzz(n) { for (let i = 1; i <= n; i++) { if (i % 3 === 0 && i % 5 === 0) { console.log('FizzBuzz'); } else if (i % 3 === 0) { console.log('Fizz'); } else if (i % 5 === 0) { console.log('Buzz'); } else { console.log(i); } } } fizzBuzz(15);

एक सरणी से डुप्लिकेट हटाएँ

एक फ़ंक्शन लिखें जो एक सरणी से डुप्लिकेट तत्वों को हटाता है।

स्पष्टीकरण: इसे प्राप्त करने का एक आधुनिक और संक्षिप्त तरीका Set का उपयोग करना है। सेट केवल अद्वितीय मानों को संग्रहीत करते हैं। आप सरणी को एक सेट में और फिर वापस एक सरणी में बदल सकते हैं।

function removeDuplicates(arr) { return [...new Set(arr)]; } console.log(removeDuplicates([1, 2, 2, 3, 4, 4, 5])); // [1, 2, 3, 4, 5]

एनाग्राम जाँच

जांचने के लिए एक फ़ंक्शन लिखें कि क्या दो स्ट्रिंग एक दूसरे के एनाग्राम हैं।

स्पष्टीकरण: एनाग्राम वे शब्द होते हैं जो किसी अन्य के अक्षरों को पुनर्व्यवस्थित करके बनते हैं। इसकी जाँच के लिए, हम स्ट्रिंग को साफ़, सॉर्ट और तुलना कर सकते हैं। सफ़ाई में गैर-अल्फ़ान्यूमेरिक वर्णों को हटाना और एक ही प्रारूप (अपरकेस/लोअरकेस) में बदलना शामिल है।

function isAnagram(str1, str2) { const clean = (str) => str.replace(/[^a-z0-9]/gi, '').toLowerCase(); const sorted = (str) => clean(str).split('').sort().join(''); return sorted(str1) === sorted(str2); } console.log(isAnagram('listen', 'silent')); // true console.log(isAnagram('hello', 'world')); // false

फैक्टोरियल की गणना करें

एक गैर-ऋणात्मक पूर्णांक के फैक्टोरियल की गणना करने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: एक संख्या का फैक्टोरियल (n!) n से कम या उसके बराबर सभी धनात्मक पूर्णांकों का गुणनफल होता है। हम 1 से n तक की संख्याओं को गुणा करके इसे पुनरावृत्त रूप से गणना कर सकते हैं।

function factorial(n) { if (n < 0) return undefined; // नकारात्मक संख्याओं के लिए फैक्टोरियल परिभाषित नहीं है if (n === 0) return 1; let result = 1; for (let i = 1; i <= n; i++) { result *= i; } return result; } console.log(factorial(5)); // 120

एक सरणी में सभी संख्याओं का योग करें

एक फ़ंक्शन लिखें जो एक सरणी में सभी संख्याओं का योग लौटाता है।

स्पष्टीकरण: आप reduce विधि का उपयोग कर सकते हैं, जो एक सरणी से एक एकल मान जमा करने के लिए आदर्श है। यह एक कॉलबैक फ़ंक्शन और एक प्रारंभिक मान (योग के लिए 0) लेता है।

function sumArray(arr) { return arr.reduce((accumulator, currentValue) => accumulator + currentValue, 0); } console.log(sumArray([1, 2, 3, 4])); // 10

एक नेस्टेड सरणी को समतल करें

एक नेस्टेड सरणी को समतल करने के लिए एक फ़ंक्शन लिखें। सरलता के लिए, केवल एक स्तर के नेस्टिंग को मानें।

स्पष्टीकरण: नेस्टिंग के एक ही स्तर के लिए, आप स्प्रेड ऑपरेटर या flat() विधि (ES2019) के साथ Array.prototype.concat() का उपयोग कर सकते हैं।

function flattenArray(arr) { // flat() का उपयोग करके (यदि ES2019+ स्वीकार्य है तो सरल) // return arr.flat(); // reduce और concat का उपयोग करके return arr.reduce((acc, val) => acc.concat(val), []); } console.log(flattenArray([1, [2, 3], 4, [5]])); // [1, 2, 3, 4, 5]

एक स्ट्रिंग में स्वरों की गणना करें

एक फ़ंक्शन लिखें जो दी गई स्ट्रिंग में स्वरों (a, e, i, o, u) की संख्या गिनता है।

स्पष्टीकरण: स्ट्रिंग के माध्यम से पुनरावृति करें (केस-संवेदी नहीं) और जांचें कि क्या प्रत्येक वर्ण एक स्वर है। एक काउंटर बनाए रखें।

function countVowels(str) { const vowels = 'aeiou'; let count = 0; for (let char of str.toLowerCase()) { if (vowels.includes(char)) { count++; } } return count; } console.log(countVowels('Hello World')); // 3

एक वाक्य में प्रत्येक शब्द का पहला अक्षर कैपिटलाइज़ करें

एक फ़ंक्शन लिखें जो एक वाक्य को शीर्षक प्रारूप में बदलता है (प्रत्येक शब्द का पहला अक्षर कैपिटलाइज़ किया गया)।

स्पष्टीकरण: वाक्य को शब्दों में विभाजित करें, फिर प्रत्येक शब्द के माध्यम से पुनरावृति करें, पहले अक्षर को कैपिटलाइज़ करें और शेष को लोअरकेस करें। अंत में, शब्दों को फिर से जोड़ें।

function titleCase(str) { return str.toLowerCase().split(' ').map(word => { return word.charAt(0).toUpperCase() + word.slice(1); }).join(' '); } console.log(titleCase('i am a little tea pot')); // 'I Am A Little Tea Pot'

दो योगों की समस्या

एक पूर्णांक सरणी nums और एक पूर्णांक target दिया गया है, उन दो संख्याओं के सूचकांक लौटाएँ जिनकी योग target है।

स्पष्टीकरण: एक सामान्य दृष्टिकोण पुनरावृति करते समय संख्याओं और उनके सूचकांकों को संग्रहीत करने के लिए एक हैश मैप (या एक JavaScript ऑब्जेक्ट) का उपयोग करना है। प्रत्येक संख्या के लिए, जांचें कि क्या target - current_number मैप में मौजूद है।

function twoSum(nums, target) { const map = {}; for (let i = 0; i < nums.length; i++) { const complement = target - nums[i]; if (map[complement] !== undefined) { return [map[complement], i]; } map[nums[i]] = i; } return []; // या null, या यदि कोई समाधान नहीं है तो त्रुटि फेंकें } console.log(twoSum([2, 7, 11, 15], 9)); // [0, 1]

क्लोजर का उपयोग करके एक काउंटर लागू करें

एक फ़ंक्शन बनाएँ जो एक काउंटर फ़ंक्शन लौटाता है। जब भी लौटे हुए फ़ंक्शन को बुलाया जाता है, तो उसे एक गणना को बढ़ाना और वापस करना चाहिए।

स्पष्टीकरण: यह क्लोजर को प्रदर्शित करता है। आंतरिक फ़ंक्शन में बाहरी फ़ंक्शन के दायरे से count वेरिएबल तक पहुंच होती है, भले ही बाहरी फ़ंक्शन ने निष्पादित करना समाप्त कर दिया हो।

function createCounter() { let count = 0; return function() { count++; return count; }; } const counter1 = createCounter(); console.log(counter1()); // 1 console.log(counter1()); // 2 const counter2 = createCounter(); console.log(counter2()); // 1

पहला गैर-दोहराव वाला वर्ण ज्ञात करें

एक फ़ंक्शन लिखें जो एक स्ट्रिंग में पहला गैर-दोहराव वाला वर्ण ज्ञात करता है।

स्पष्टीकरण: आप वर्णों की आवृत्तियों को गिनने के लिए एक हैश मैप का उपयोग कर सकते हैं। सबसे पहले, आवृत्ति मैप बनाने के लिए स्ट्रिंग के माध्यम से पुनरावृति करें। फिर, स्ट्रिंग के माध्यम से फिर से पुनरावृति करें और 1 की गणना के साथ पहला वर्ण लौटाएँ।

function firstNonRepeatingChar(str) { const charCount = {}; for (const char of str) { charCount[char] = (charCount[char] || 0) + 1; } for (const char of str) { if (charCount[char] === 1) { return char; } } return null; // या कोई संकेतक यदि सभी दोहराए जाते हैं } console.log(firstNonRepeatingChar('aabbcdeeff')); // 'c' console.log(firstNonRepeatingChar('swiss')); // 'w'

सरणी खंडन (Array Chunking)

एक फ़ंक्शन लिखें जो एक सरणी को एक निर्दिष्ट आकार के समूहों में विभाजित करता है।

स्पष्टीकरण: सरणी के माध्यम से पुनरावृति करें, निर्दिष्ट आकार के 'स्लाइस' लें और उन्हें एक नई सरणी में धकेलें। उस मामले को संभालें जहाँ अंतिम खंड छोटा हो सकता है।

function chunkArray(arr, size) { const chunked = []; let index = 0; while (index < arr.length) { chunked.push(arr.slice(index, index + size)); index += size; } return chunked; } console.log(chunkArray([1, 2, 3, 4, 5, 6, 7], 3)); // [[1, 2, 3], [4, 5, 6], [7]]

जाँचें कि क्या कोई संख्या अभाज्य है

यह निर्धारित करने के लिए एक फ़ंक्शन लिखें कि दी गई संख्या एक अभाज्य संख्या है या नहीं।

स्पष्टीकरण: एक अभाज्य संख्या 1 से बड़ी एक प्राकृतिक संख्या है जिसका 1 और स्वयं के अलावा कोई धनात्मक भाजक नहीं होता है। संख्या के वर्गमूल तक 2 से पुनरावृति करें, विभाज्यता की जाँच करें। 1 और 2 जैसे सीमांत मामलों को संभालें।

function isPrime(num) { if (num <= 1) return false; if (num <= 3) return true; if (num % 2 === 0 || num % 3 === 0) return false; for (let i = 5; i * i <= num; i = i + 6) { if (num % i === 0 || num % (i + 2) === 0) return false; } return true; } console.log(isPrime(7)); // true console.log(isPrime(10)); // false

एक स्ट्रिंग में सबसे लंबा शब्द ज्ञात करें

एक फ़ंक्शन लिखें जो एक वाक्य में सबसे लंबा शब्द ज्ञात करता है।

स्पष्टीकरण: स्ट्रिंग को शब्दों की सरणी में विभाजित करें। फिर, सरणी के माध्यम से पुनरावृति करें, अब तक मिले सबसे लंबे शब्द (या उसकी लंबाई) का ट्रैक रखें।

function findLongestWord(str) { const words = str.split(' '); let longestWord = ''; for (const word of words) { // यदि आवश्यक हो तो शब्दों को साफ़ करें (उदा. विराम चिह्न हटाएँ) if (word.length > longestWord.length) { longestWord = word; } } return longestWord; } console.log(findLongestWord('The quick brown fox jumped over the lazy dog')); // 'jumped'

`Array.prototype.map` को लागू करें

Array.prototype.map फ़ंक्शन का अपना स्वयं का संस्करण लागू करें।

स्पष्टीकरण: map फ़ंक्शन एक कॉलबैक फ़ंक्शन लेता है और मूल सरणी के प्रत्येक तत्व पर कॉलबैक फ़ंक्शन को लागू करके एक नई सरणी बनाता है। आपके फ़ंक्शन को सरणी के माध्यम से पुनरावृति करनी चाहिए और नई सरणी का निर्माण करना चाहिए।

function myMap(arr, callback) { const mappedArray = []; for (let i = 0; i < arr.length; i++) { mappedArray.push(callback(arr[i], i, arr)); } return mappedArray; } const numbers = [1, 4, 9]; const roots = myMap(numbers, Math.sqrt); console.log(roots); // [1, 2, 3]

`Array.prototype.filter` को लागू करें

Array.prototype.filter फ़ंक्शन का अपना स्वयं का संस्करण लागू करें।

स्पष्टीकरण: filter फ़ंक्शन एक कॉलबैक फ़ंक्शन लेता है और प्रदान किए गए कॉलबैक फ़ंक्शन द्वारा लागू परीक्षण को पास करने वाले सभी तत्वों के साथ एक नई सरणी बनाता है।

function myFilter(arr, callback) { const filteredArray = []; for (let i = 0; i < arr.length; i++) { if (callback(arr[i], i, arr)) { filteredArray.push(arr[i]); } } return filteredArray; } const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present']; const result = myFilter(words, word => word.length > 6); console.log(result); // ['exuberant', 'destruction', 'present']

`Array.prototype.reduce` को लागू करें

Array.prototype.reduce फ़ंक्शन का अपना स्वयं का संस्करण लागू करें।

स्पष्टीकरण: reduce फ़ंक्शन सरणी के प्रत्येक तत्व पर उपयोगकर्ता द्वारा प्रदान किए गए 'रिड्यूसर' कॉलबैक फ़ंक्शन को निष्पादित करता है, पिछले तत्व की गणना का वापसी मूल्य पास करता है। सरणी के सभी तत्वों के माध्यम से रिड्यूसर को चलाने का अंतिम परिणाम एक एकल मान है। प्रारंभिक मान तर्क को संभालें।

function myReduce(arr, callback, initialValue) { let accumulator = initialValue; let startIndex = 0; if (initialValue === undefined) { if (arr.length === 0) throw new TypeError('प्रारंभिक मान के बिना एक खाली सरणी का रिड्यूस'); accumulator = arr[0]; startIndex = 1; } for (let i = startIndex; i < arr.length; i++) { accumulator = callback(accumulator, arr[i], i, arr); } return accumulator; } const array1 = [1, 2, 3, 4]; const sum = myReduce(array1, (acc, curr) => acc + curr, 0); console.log(sum); // 10

मेमोइज़ेशन - फाइबोनैचि अनुक्रम

प्रदर्शन को अनुकूलित करने के लिए मेमोइज़ेशन का उपयोग करके एक फाइबोनैचि फ़ंक्शन लागू करें।

स्पष्टीकरण: फाइबोनैचि अनुक्रम में दोहराई जाने वाली गणनाएँ शामिल होती हैं। मेमोइज़ेशन महंगी फ़ंक्शन कॉलों के परिणामों को संग्रहीत करता है और जब समान इनपुट फिर से होते हैं तो कैश किया गया परिणाम लौटाता है।

function memoizedFib() { const cache = {}; function fib(n) { if (n in cache) { return cache[n]; } if (n <= 1) { return n; } const result = fib(n - 1) + fib(n - 2); cache[n] = result; return result; } return fib; } const fibonacci = memoizedFib(); console.log(fibonacci(10)); // 55 console.log(fibonacci(40)); // 102334155 (बिना मेमोइज़ेशन के तुलना में बहुत तेज़)

संतुलित कोष्ठक की जाँच करें

जांचने के लिए एक फ़ंक्शन लिखें कि क्या कोष्ठक {}[]() वाली एक स्ट्रिंग संतुलित है।

स्पष्टीकरण: एक स्टैक का उपयोग करें। जब आपको एक उद्घाटन कोष्ठक मिलता है, तो उसे स्टैक में धकेलें। जब आपको एक समापन कोष्ठक मिलता है, तो जांचें कि क्या स्टैक खाली है या क्या शीर्ष तत्व संगत उद्घाटन कोष्ठक है। यदि यह मेल खाता है, तो तत्व को स्टैक से पॉप करें। यदि नहीं, या यदि स्टैक खाली है, तो यह असंतुलित है। अंत में, एक खाली स्टैक का मतलब है कि यह संतुलित है।

function isBalanced(str) { const stack = []; const map = { '(': ')', '{': '}', '[': ']' }; for (let char of str) { if (map[char]) { stack.push(char); } else if (Object.values(map).includes(char)) { if (stack.length === 0) return false; const lastOpen = stack.pop(); if (map[lastOpen] !== char) return false; } } return stack.length === 0; } console.log(isBalanced('({[]})')); // true console.log(isBalanced('([)]')); // false

एक साधारण कतार लागू करें

enqueue (अंत में जोड़ें) और dequeue (शुरुआत से हटाएँ) विधियों के साथ एक कतार (Queue) डेटा संरचना लागू करें।

स्पष्टीकरण: एक कतार FIFO (First-In, First-Out) सिद्धांत का पालन करती है। एक सरणी का उपयोग किया जा सकता है, enqueue के लिए push और dequeue के लिए shift के साथ।

class Queue { constructor() { this.items = []; } enqueue(element) { this.items.push(element); } dequeue() { if (this.isEmpty()) return 'Underflow'; return this.items.shift(); } front() { if (this.isEmpty()) return 'No elements in Queue'; return this.items[0]; } isEmpty() { return this.items.length === 0; } } const q = new Queue(); q.enqueue(10); q.enqueue(20); console.log(q.dequeue()); // 10 console.log(q.front()); // 20

एक साधारण स्टैक लागू करें

push (शीर्ष पर जोड़ें) और pop (शीर्ष से हटाएँ) विधियों के साथ एक स्टैक (Stack) डेटा संरचना लागू करें।

स्पष्टीकरण: एक स्टैक LIFO (Last-In, First-Out) सिद्धांत का पालन करता है। एक सरणी का उपयोग किया जा सकता है, push और pop विधियों के साथ।

class Stack { constructor() { this.items = []; } push(element) { this.items.push(element); } pop() { if (this.isEmpty()) return 'Underflow'; return this.items.pop(); } peek() { return this.items[this.items.length - 1]; } isEmpty() { return this.items.length === 0; } } const s = new Stack(); s.push(10); s.push(20); console.log(s.pop()); // 20 console.log(s.peek()); // 10

अनुक्रम में लापता संख्या ज्ञात करें

एक सरणी दी गई है जिसमें 0, 1, 2, ..., n से लिए गए n विशिष्ट संख्याएँ हैं, सरणी में लापता संख्या ज्ञात करें।

स्पष्टीकरण: 0 से n तक की संख्याओं का योग n*(n+1)/2 सूत्र का उपयोग करके गणना किया जा सकता है। सरणी तत्वों का वास्तविक योग गणना किया जा सकता है। इन दो योगों के बीच का अंतर लापता संख्या होगी।

function findMissingNumber(nums) { const n = nums.length; const expectedSum = n * (n + 1) / 2; const actualSum = nums.reduce((sum, num) => sum + num, 0); return expectedSum - actualSum; } console.log(findMissingNumber([3, 0, 1])); // 2 console.log(findMissingNumber([9, 6, 4, 2, 3, 5, 7, 0, 1])); // 8

डेबाउंस फ़ंक्शन

एक डेबाउंस फ़ंक्शन लागू करें। डेबाउंस यह सुनिश्चित करता है कि एक फ़ंक्शन को तब तक फिर से नहीं बुलाया जाएगा जब तक कि एक निश्चित समय बीत न जाए बिना इसे फिर से बुलाया गया हो।

स्पष्टीकरण: setTimeout और clearTimeout का उपयोग करें। हर बार जब डेबाउंस फ़ंक्शन को बुलाया जाता है, तो यह पिछले टाइमआउट को साफ़ करता है और एक नया सेट करता है। वास्तविक फ़ंक्शन कॉल तभी होती है जब टाइमआउट पूरा हो जाता है।

function debounce(func, delay) { let timeoutId; return function(...args) { clearTimeout(timeoutId); timeoutId = setTimeout(() => { func.apply(this, args); }, delay); }; } // उपयोग का उदाहरण: const sayHello = () => console.log('Hello!'); const debouncedHello = debounce(sayHello, 1000); debouncedHello(); // 1 सेकंड के बाद बुलाया जाता है (यदि फिर से नहीं बुलाया जाता है) debouncedHello(); // टाइमर रीसेट करता है debouncedHello(); // टाइमर रीसेट करता है, इस कॉल के 1 सेकंड बाद निष्पादित होगा।

थ्रॉटल फ़ंक्शन

एक थ्रॉटल फ़ंक्शन लागू करें। थ्रॉटल यह सुनिश्चित करता है कि एक फ़ंक्शन को एक निर्दिष्ट समय अंतराल में अधिकतम एक बार बुलाया जाए।

स्पष्टीकरण: यह इंगित करने के लिए एक ध्वज का उपयोग करें कि क्या कॉल की अनुमति है। जब बुलाया जाता है, यदि अनुमति दी जाती है, तो फ़ंक्शन को निष्पादित करें, ध्वज को असत्य पर सेट करें और अंतराल के बाद ध्वज को रीसेट करने के लिए setTimeout का उपयोग करें।

function throttle(func, limit) { let inThrottle = false; return function(...args) { if (!inThrottle) { func.apply(this, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } // उपयोग का उदाहरण: const logScroll = () => console.log('Scrolling...'); const throttledScroll = throttle(logScroll, 1000); // window.addEventListener('scroll', throttledScroll); // प्रति सेकंड अधिकतम एक बार लॉग करेगा।

फंक्शन करीइंग

एक फ़ंक्शन लिखें जो दो तर्कों के साथ एक फ़ंक्शन लेता है और उसका एक करीड संस्करण लौटाता है।

स्पष्टीकरण: करीइंग एक फ़ंक्शन को कई तर्कों के साथ फ़ंक्शंस के अनुक्रम में बदल देता है, प्रत्येक एक एकल तर्क लेता है। f(a, b) f(a)(b) बन जाता है।

function curry(fn) { return function(a) { return function(b) { return fn(a, b); }; }; } function add(a, b) { return a + b; } const curriedAdd = curry(add); const add5 = curriedAdd(5); console.log(add5(3)); // 8 console.log(curriedAdd(10)(20)); // 30

एक ऑब्जेक्ट का गहरा क्लोनिंग

एक JavaScript ऑब्जेक्ट का गहरा क्लोनिंग करने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: एक उथला क्लोन केवल शीर्ष-स्तरीय गुणों की प्रतिलिपि बनाता है। एक गहरा क्लोन सभी गुणों को पुनरावृत्त रूप से कॉपी करता है, जिसमें नेस्टेड ऑब्जेक्ट और सरणियाँ शामिल हैं। एक सरल तरीका (सीमाओं के साथ, उदाहरण के लिए, फ़ंक्शन, तिथियां, नियमित अभिव्यक्ति को अच्छी तरह से नहीं संभालता है) JSON.parse(JSON.stringify(obj)) का उपयोग कर रहा है। एक पुनरावर्ती दृष्टिकोण अधिक मज़बूत है।

function deepClone(obj) { // सरल संस्करण (सीमाओं के साथ) try { return JSON.parse(JSON.stringify(obj)); } catch (e) { console.error("क्लोनिंग विफल:", e); return null; } // अधिक मज़बूत पुनरावर्ती संस्करण (मूल उदाहरण): /* if (obj === null || typeof obj !== 'object') { return obj; } let clone = Array.isArray(obj) ? [] : {}; for (let key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { clone[key] = deepClone(obj[key]); } } return clone; */ } const original = { a: 1, b: { c: 2 } }; const cloned = deepClone(original); cloned.b.c = 3; console.log(original.b.c); // 2 (यह दर्शाता है कि यह एक गहरा क्लोन है) console.log(cloned.b.c); // 3

किसी ऑब्जेक्ट से कुंजी प्राप्त करें

किसी ऑब्जेक्ट से कुंजियों का एक सरणी (array) कैसे प्राप्त करें?

स्पष्टीकरण: Object.keys(obj) का उपयोग करें।

function getKeys(obj) { return Object.keys(obj); } console.log(getKeys({a: 1, b: 2})); // ['a', 'b']

किसी ऑब्जेक्ट से मान प्राप्त करें

किसी ऑब्जेक्ट से मानों का एक सरणी (array) कैसे प्राप्त करें?

स्पष्टीकरण: Object.values(obj) का उपयोग करें।

function getValues(obj) { return Object.values(obj); } console.log(getValues({a: 1, b: 2})); // [1, 2]

जाँचें कि क्या किसी सरणी में कोई मान शामिल है

यह कैसे जांचें कि क्या किसी सरणी में कोई विशिष्ट मान है?

स्पष्टीकरण: Array.prototype.includes(value) का उपयोग करें।

function checkIncludes(arr, val) { return arr.includes(val); } console.log(checkIncludes([1, 2, 3], 2)); // true

दो सरणियों को मर्ज करें

दो सरणियों को एक में कैसे मर्ज करें?

स्पष्टीकरण: स्प्रेड सिंटैक्स (...) या Array.prototype.concat() का उपयोग करें।

function mergeArrays(arr1, arr2) { return [...arr1, ...arr2]; } console.log(mergeArrays([1, 2], [3, 4])); // [1, 2, 3, 4]

ग्लोबल स्कोप में 'this' समझाएं

एक ब्राउज़र में ग्लोबल स्कोप में this किसे संदर्भित करता है?

स्पष्टीकरण: ग्लोबल एग्जीक्यूशन कॉन्टेक्स्ट (किसी भी फ़ंक्शन के बाहर) में, this ग्लोबल ऑब्जेक्ट को संदर्भित करता है, जो वेब ब्राउज़र में window है।

console.log(this === window); // true (एक ब्राउज़र वातावरण में)

एक ऑब्जेक्ट मेथड में 'this' समझाएं

एक ऑब्जेक्ट के मेथड के अंदर उपयोग किए जाने पर this किसे संदर्भित करता है?

स्पष्टीकरण: जब एक फ़ंक्शन को एक ऑब्जेक्ट के मेथड के रूप में कॉल किया जाता है, तो this उस ऑब्जेक्ट को संदर्भित करता है जिस पर मेथड को कॉल किया जाता है।

const myObject = { prop: 'Hello', greet() { return this.prop; } }; console.log(myObject.greet()); // 'Hello'

एरो फ़ंक्शंस के साथ 'this' समझाएं

एरो फ़ंक्शंस this को कैसे संभालते हैं?

स्पष्टीकरण: एरो फ़ंक्शंस का अपना this कॉन्टेक्स्ट नहीं होता है। इसके बजाय, वे अपने आसपास के (लेक्सिकल) स्कोप से this को इनहेरिट करते हैं जहाँ उन्हें परिभाषित किया जाता है।

function MyClass() { this.value = 42; setTimeout(() => { console.log(this.value); // 42 दिखाता है क्योंकि 'this' इनहेरिट किया गया है }, 100); } new MyClass();

`let`, `const` और `var` के बीच अंतर

let, const और var के बीच मुख्य अंतर क्या हैं?

स्पष्टीकरण: var में फ़ंक्शन स्कोप होता है और वह होइस्टेड होता है। let और const में ब्लॉक स्कोप होता है और वे होइस्टेड होते हैं, लेकिन डिक्लेरेशन तक 'टेम्पोरल डेड ज़ोन' में होते हैं। const को इनिशियलाइज़ किया जाना चाहिए और उसे फिर से असाइन नहीं किया जा सकता है।

function scopeTest() { var a = 1; let b = 2; const c = 3; if (true) { var a = 10; // 'a' को फिर से डिक्लेयर करता है और बाहरी 'a' को प्रभावित करता है let b = 20; // ब्लॉक के अंदर नया 'b' // const c = 30; // एक नया 'c' होगा console.log(a, b, c); // 10, 20, 3 } console.log(a, b, c); // 10, 2, 3 } scopeTest();

प्रॉमिस क्या है?

जावास्क्रिप्ट में प्रॉमिस क्या है, समझाएं।

स्पष्टीकरण: एक प्रॉमिस एक ऑब्जेक्ट है जो एक असिंक्रोनस ऑपरेशन के अंतिम समापन (या विफलता) और उसके परिणामस्वरूप मूल्य का प्रतिनिधित्व करता है। यह तीन अवस्थाओं में से किसी एक में हो सकता है: लंबित (pending), पूर्ण (fulfilled) या अस्वीकृत (rejected)।

const myPromise = new Promise((resolve, reject) => { setTimeout(() => { resolve('सफलता!'); // reject('त्रुटि!'); }, 1000); }); myPromise .then(result => console.log(result)) .catch(error => console.error(error));

`async/await` का उपयोग करना

async और await प्रॉमिस के साथ काम करना कैसे आसान बनाते हैं?

स्पष्टीकरण: async/await प्रॉमिस पर एक सरल सिंटैक्स प्रदान करता है, जिससे असिंक्रोनस कोड थोड़ा और सिंक्रोनस कोड जैसा दिखता और व्यवहार करता है। एक async फ़ंक्शन हमेशा एक प्रॉमिस लौटाता है, और await तब तक निष्पादन को रोकता है जब तक कि एक प्रॉमिस हल या अस्वीकृत न हो जाए।

function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function run() { console.log('शुरू हो रहा है...'); await delay(1000); console.log('1 सेकंड इंतजार किया।'); await delay(500); console.log('और 0.5 सेकंड इंतजार किया।'); return 'हो गया!'; } run().then(console.log);

स्ट्रिंग को नंबर में बदलें

एक टेक्स्ट स्ट्रिंग को नंबर में कैसे बदलें?

स्पष्टीकरण: parseInt(), parseFloat() या यूनरी प्लस ऑपरेटर (+) का उपयोग करें।

const str = '123.45'; console.log(parseInt(str)); // 123 console.log(parseFloat(str)); // 123.45 console.log(+str); // 123.45

नंबर को स्ट्रिंग में बदलें

एक नंबर को टेक्स्ट स्ट्रिंग में कैसे बदलें?

स्पष्टीकरण: String(), number.toString() या स्ट्रिंग कॉनकेटिनेशन का उपयोग करें।

const num = 123; console.log(String(num)); // '123' console.log(num.toString()); // '123' console.log('' + num); // '123'

`JSON.stringify` क्या है?

JSON.stringify क्या करता है?

स्पष्टीकरण: यह एक जावास्क्रिप्ट ऑब्जेक्ट या वैल्यू को JSON स्ट्रिंग में बदलता है।

const obj = { name: 'Alice', age: 30 }; const jsonString = JSON.stringify(obj); console.log(jsonString); // '{"name":"Alice","age":30}'

`JSON.parse` क्या है?

JSON.parse क्या करता है?

स्पष्टीकरण: यह एक JSON स्ट्रिंग को पार्स करता है, स्ट्रिंग द्वारा वर्णित जावास्क्रिप्ट वैल्यू या ऑब्जेक्ट का निर्माण करता है।

const jsonString = '{"name":"Alice","age":30}'; const obj = JSON.parse(jsonString); console.log(obj.name); // 'Alice'

सरणियों में स्प्रेड ऑपरेटर

सरणियों के साथ स्प्रेड ऑपरेटर (spread operator) का उपयोग कैसे किया जाता है?

स्पष्टीकरण: यह एक इटरेबल (जैसे एक सरणी) को उन जगहों पर विस्तारित करने की अनुमति देता है जहाँ शून्य या अधिक तर्क या तत्व अपेक्षित होते हैं। कॉपी करने, मर्ज करने और तत्वों को जोड़ने के लिए उपयोगी।

const arr1 = [1, 2]; const arr2 = [3, 4]; const combined = [...arr1, ...arr2]; // [1, 2, 3, 4] const copy = [...arr1]; // [1, 2]

ऑब्जेक्ट्स में स्प्रेड ऑपरेटर

ऑब्जेक्ट्स के साथ स्प्रेड ऑपरेटर (spread operator) का उपयोग कैसे किया जाता है?

स्पष्टीकरण: यह ऑब्जेक्ट गुणों को कॉपी और मर्ज करने की अनुमति देता है।

const obj1 = { a: 1, b: 2 }; const obj2 = { b: 3, c: 4 }; const merged = { ...obj1, ...obj2 }; // { a: 1, b: 3, c: 4 } const copy = { ...obj1 }; // { a: 1, b: 2 }

सरणी डीस्ट्रक्चरिंग

एक उदाहरण के साथ सरणी डीस्ट्रक्चरिंग समझाएं।

स्पष्टीकरण: यह एक सिंटैक्स है जो सरणियों से मानों को अलग-अलग वेरिएबल्स में अनपैक करने की अनुमति देता है।

const [a, b] = [10, 20]; console.log(a); // 10 console.log(b); // 20 const [x, , z] = [1, 2, 3]; console.log(z); // 3

ऑब्जेक्ट डीस्ट्रक्चरिंग

एक उदाहरण के साथ ऑब्जेक्ट डीस्ट्रक्चरिंग समझाएं।

स्पष्टीकरण: यह ऑब्जेक्ट के गुणों को अलग-अलग वेरिएबल्स में अनपैक करने की अनुमति देता है।

const person = { name: 'Bob', age: 25 }; const { name, age } = person; console.log(name); // 'Bob' console.log(age); // 25 const { name: personName } = person; console.log(personName); // 'Bob'

`call` लागू करें

आप Function.prototype.call का एक बुनियादी संस्करण कैसे लागू करेंगे?

स्पष्टीकरण: call एक फ़ंक्शन को एक निर्दिष्ट this मान और व्यक्तिगत रूप से प्रदान किए गए तर्कों के साथ इनवोक करता है। आप फ़ंक्शन को this कॉन्टेक्स्ट से अटैच कर सकते हैं, उसे कॉल कर सकते हैं, और फिर उसे हटा सकते हैं।

Function.prototype.myCall = function(context, ...args) { context = context || window; const uniqueId = Symbol(); // एक अद्वितीय कुंजी का उपयोग करें context[uniqueId] = this; const result = context[uniqueId](...args); delete context[uniqueId]; return result; } function greet(greeting, punctuation) { console.log(`${greeting}, ${this.name}${punctuation}`); } greet.myCall({ name: 'Charlie' }, 'Hi', '!'); // Hi, Charlie!

`apply` लागू करें

आप Function.prototype.apply का एक बुनियादी संस्करण कैसे लागू करेंगे?

स्पष्टीकरण: apply call के समान है, लेकिन तर्कों को एक सरणी के रूप में स्वीकार करता है।

Function.prototype.myApply = function(context, argsArray) { context = context || window; const uniqueId = Symbol(); context[uniqueId] = this; const result = context[uniqueId](...(argsArray || [])); delete context[uniqueId]; return result; } function greet(greeting, punctuation) { console.log(`${greeting}, ${this.name}${punctuation}`); } greet.myApply({ name: 'David' }, ['Hello', '.']); // Hello, David.

इवेंट लूप समझाएं

जावास्क्रिप्ट के इवेंट लूप को संक्षेप में समझाएं।

स्पष्टीकरण: जावास्क्रिप्ट सिंगल-थ्रेडेड है, लेकिन यह इवेंट लूप का उपयोग करके कंकरेंसी प्राप्त करता है। कॉल स्टैक सिंक्रोनस कोड को संभालता है। वेब APIs असिंक्रोनस ऑपरेशन (जैसे setTimeout, fetch) को संभालती हैं। जब एक असिंक्रोनस ऑपरेशन समाप्त होता है, तो उसका कॉलबैक कॉलबैक क्यू (या प्रॉमिस के लिए माइक्रोटास्क क्यू) में जाता है। इवेंट लूप लगातार जांचता है कि क्या कॉल स्टैक खाली है; यदि यह खाली है, तो यह निष्पादन के लिए क्यू से अगला कॉलबैक स्टैक में ले जाता है।

console.log('शुरू'); setTimeout(() => { console.log('टाइमआउट कॉलबैक'); // कॉलबैक क्यू में जाता है }, 0); Promise.resolve().then(() => { console.log('प्रॉमिस रिजॉल्व हुआ'); // माइक्रोटास्क क्यू में जाता है }); console.log('समाप्त'); // आउटपुट ऑर्डर: शुरू, समाप्त, प्रॉमिस रिजॉल्व हुआ, टाइमआउट कॉलबैक // (माइक्रोटास्क मैक्रोटास्क/कॉलबैक से पहले निष्पादित होते हैं)

बाइनरी सर्च

एक सॉर्टेड सरणी के लिए एक बाइनरी सर्च फ़ंक्शन लागू करें।

स्पष्टीकरण: बाइनरी सर्च एक सॉर्टेड सरणी में एक तत्व को खोज के अंतराल को आधा करके कुशलता से पाता है। यदि सर्च कुंजी का मान अंतराल के मध्य में तत्व से कम है, तो यह अंतराल को निचले आधे तक कम कर देता है। अन्यथा, यह ऊपरी आधे तक कम कर देता है। यह तब तक किया जाता है जब तक मान नहीं मिल जाता या अंतराल खाली नहीं हो जाता।

function binarySearch(sortedArray, key) { let start = 0; let end = sortedArray.length - 1; while (start <= end) { let middle = Math.floor((start + end) / 2); if (sortedArray[middle] === key) { return middle; // मिल गया } else if (sortedArray[middle] < key) { start = middle + 1; // दाहिने आधे में खोजें } else { end = middle - 1; // बाएं आधे में खोजें } } return -1; // नहीं मिला } console.log(binarySearch([1, 3, 5, 7, 9, 11], 7)); // 3 console.log(binarySearch([1, 3, 5, 7, 9, 11], 2)); // -1

मर्ज सॉर्ट

मर्ज सॉर्ट एल्गोरिथम लागू करें।

स्पष्टीकरण: मर्ज सॉर्ट एक डिवाइड-एंड-कॉन्कर एल्गोरिथम है। यह इनपुट सरणी को दो हिस्सों में विभाजित करता है, खुद को दोनों हिस्सों के लिए कॉल करता है, और फिर दोनों सॉर्टेड हिस्सों को मर्ज करता है। मर्ज फ़ंक्शन महत्वपूर्ण है; यह दो सॉर्टेड सब-सरणियों को एक सॉर्टेड सरणी में जोड़ता है।

function mergeSort(arr) { if (arr.length <= 1) return arr; const mid = Math.floor(arr.length / 2); const left = mergeSort(arr.slice(0, mid)); const right = mergeSort(arr.slice(mid)); return merge(left, right); } function merge(left, right) { let result = []; let leftIndex = 0; let rightIndex = 0; while (leftIndex < left.length && rightIndex < right.length) { if (left[leftIndex] < right[rightIndex]) { result.push(left[leftIndex]); leftIndex++; } else { result.push(right[rightIndex]); rightIndex++; } } return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex)); } console.log(mergeSort([38, 27, 43, 3, 9, 82, 10])); // [3, 9, 10, 27, 38, 43, 82]

क्विक सॉर्ट

क्विक सॉर्ट एल्गोरिथम लागू करें।

स्पष्टीकरण: क्विक सॉर्ट भी एक डिवाइड-एंड-कॉन्कर एल्गोरिथम है। यह एक तत्व को पिवट के रूप में चुनता है और दिए गए सरणी को चुने हुए पिवट के चारों ओर विभाजित करता है। पिवट से छोटे तत्व बाईं ओर जाते हैं, और बड़े तत्व दाहिनी ओर जाते हैं। फिर यह सब-सरणियों को रिकर्सिव रूप से सॉर्ट करता है।

function quickSort(arr) { if (arr.length <= 1) return arr; const pivot = arr[arr.length - 1]; const left = []; const right = []; for (let i = 0; i < arr.length - 1; i++) { if (arr[i] < pivot) { left.push(arr[i]); } else { right.push(arr[i]); } } return [...quickSort(left), pivot, ...quickSort(right)]; } console.log(quickSort([10, 8, 2, 1, 6, 3, 9, 4, 7, 5])); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

बबल सॉर्ट

बबल सॉर्ट एल्गोरिथम लागू करें।

स्पष्टीकरण: बबल सॉर्ट एक सरल सॉर्टिंग एल्गोरिथम है जो सूची को बार-बार पार करता है, आसन्न तत्वों की तुलना करता है और यदि वे गलत क्रम में हैं तो उन्हें स्वैप करता है। सूची के माध्यम से पास तब तक दोहराया जाता है जब तक सूची सॉर्ट नहीं हो जाती।

function bubbleSort(arr) { let n = arr.length; let swapped; do { swapped = false; for (let i = 0; i < n - 1; i++) { if (arr[i] > arr[i + 1]) { [arr[i], arr[i + 1]] = [arr[i + 1], arr[i]]; // स्वैप करें swapped = true; } } n--; // अनुकूलन: अंतिम तत्व पहले से ही अपनी जगह पर है } while (swapped); return arr; } console.log(bubbleSort([64, 34, 25, 12, 22, 11, 90])); // [11, 12, 22, 25, 34, 64, 90]

सबसे लंबी सबस्ट्रिंग जिसमें कोई दोहराए गए वर्ण नहीं हैं

दी गई स्ट्रिंग में, सबसे लंबी सबस्ट्रिंग की लंबाई ज्ञात करें जिसमें कोई दोहराए गए वर्ण नहीं हैं।

स्पष्टीकरण: 'स्लाइडिंग विंडो' तकनीक का उपयोग करें। एक विंडो (सबस्ट्रिंग) और उस विंडो में वर्णों का एक सेट रखें। दाहिने पॉइंटर को ले जाकर विंडो का विस्तार करें। यदि कोई दोहराया गया वर्ण मिलता है, तो विंडो को बाईं ओर से तब तक सिकोड़ें जब तक दोहराया गया वर्ण हटा न जाए।

function lengthOfLongestSubstring(s) { let maxLength = 0; let start = 0; const charMap = {}; for (let end = 0; end < s.length; end++) { const char = s[end]; if (charMap[char] >= start) { start = charMap[char] + 1; } charMap[char] = end; maxLength = Math.max(maxLength, end - start + 1); } return maxLength; } console.log(lengthOfLongestSubstring('abcabcbb')); // 3 ('abc') console.log(lengthOfLongestSubstring('bbbbb')); // 1 ('b') console.log(lengthOfLongestSubstring('pwwkew')); // 3 ('wke')

एक लिंक्ड लिस्ट लागू करें

add और print मेथड्स के साथ एक सरल लिंक्ड लिस्ट लागू करें।

स्पष्टीकरण: एक लिंक्ड लिस्ट एक रेखीय डेटा संरचना है जहाँ तत्व सन्निहित मेमोरी स्थानों में संग्रहीत नहीं होते हैं। प्रत्येक तत्व (नोड) अगले को इंगित करता है। हेड को प्रबंधित करने और नए नोड्स जोड़ने के लिए आपको एक Node क्लास और एक LinkedList क्लास की आवश्यकता है।

class Node { constructor(data, next = null) { this.data = data; this.next = next; } } class LinkedList { constructor() { this.head = null; } add(data) { const newNode = new Node(data); if (!this.head) { this.head = newNode; } else { let current = this.head; while (current.next) { current = current.next; } current.next = newNode; } } print() { let current = this.head; let list = ''; while (current) { list += current.data + ' -> '; current = current.next; } console.log(list + 'null'); } } const list = new LinkedList(); list.add(10); list.add(20); list.add(30); list.print(); // 10 -> 20 -> 30 -> null

एक बाइनरी सर्च ट्री (BST) लागू करें

insert और find मेथड्स के साथ एक बाइनरी सर्च ट्री लागू करें।

स्पष्टीकरण: एक BST एक नोड-आधारित बाइनरी ट्री डेटा संरचना है जिसमें निम्नलिखित गुण होते हैं: एक नोड का बायाँ सबट्री केवल उन नोड्स को शामिल करता है जिनकी कुंजियाँ नोड की कुंजी से कम हैं। एक नोड का दाहिना सबट्री केवल उन नोड्स को शामिल करता है जिनकी कुंजियाँ नोड की कुंजी से अधिक हैं। दोनों सबट्री भी बाइनरी सर्च ट्री होने चाहिए।

class Node { constructor(data) { this.data = data; this.left = null; this.right = null; } } class BST { constructor() { this.root = null; } insert(data) { const newNode = new Node(data); if (!this.root) { this.root = newNode; return; } this._insertNode(this.root, newNode); } _insertNode(node, newNode) { if (newNode.data < node.data) { if (!node.left) node.left = newNode; else this._insertNode(node.left, newNode); } else { if (!node.right) node.right = newNode; else this._insertNode(node.right, newNode); } } find(data) { return this._findNode(this.root, data); } _findNode(node, data) { if (!node) return null; if (data < node.data) return this._findNode(node.left, data); else if (data > node.data) return this._findNode(node.right, data); else return node; } } const bst = new BST(); bst.insert(10); bst.insert(5); bst.insert(15); bst.insert(7); console.log(bst.find(7)); // Node { data: 7, left: null, right: null } console.log(bst.find(12)); // null

एक सरणी को घुमाएं

एक सरणी को दाएं k चरणों तक घुमाने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: एक सरणी को घुमाने का अर्थ है उसके तत्वों को स्थानांतरित करना। दाएं रोटेशन के लिए, अंतिम तत्व पहला बन जाता है। इसे k बार दोहराना काम करता है लेकिन अक्षम है। एक बेहतर तरीका सरणी हेरफेर का उपयोग करना या नई स्थितियों की गणना करना है।

function rotateArray(nums, k) { k = k % nums.length; // उन मामलों को संभालें जहां k > लंबाई है if (k === 0) return nums; const partToMove = nums.splice(nums.length - k); nums.unshift(...partToMove); return nums; } console.log(rotateArray([1, 2, 3, 4, 5, 6, 7], 3)); // [5, 6, 7, 1, 2, 3, 4]

दो सरणियों का इंटरसेक्शन ज्ञात करें

दो सरणियाँ दी गई हैं, उनके इंटरसेक्शन (दोनों में सामान्य तत्व) की गणना करने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: एक अच्छा दृष्टिकोण एक सरणी को Set में बदलना है ताकि औसत समय में O(1) खोज हो सके। फिर, दूसरी सरणी के माध्यम से इटरेट करें और जांचें कि क्या प्रत्येक तत्व सेट में मौजूद है। मिलान इकट्ठा करें।

function intersection(nums1, nums2) { const set1 = new Set(nums1); const resultSet = new Set(); for (const num of nums2) { if (set1.has(num)) { resultSet.add(num); } } return [...resultSet]; } console.log(intersection([1, 2, 2, 1], [2, 2])); // [2] console.log(intersection([4, 9, 5], [9, 4, 9, 8, 4])); // [9, 4]

एनाग्राम को समूहबद्ध करें

स्ट्रिंग्स की एक सरणी दी गई है, एनाग्राम को एक साथ समूहबद्ध करें।

स्पष्टीकरण: प्रत्येक एनाग्राम समूह के लिए एक अद्वितीय हस्ताक्षर खोजना महत्वपूर्ण है। एक सामान्य तरीका प्रत्येक शब्द को वर्णानुक्रम में सॉर्ट करना है। जिन शब्दों का परिणाम समान सॉर्टेड स्ट्रिंग में होता है वे एनाग्राम होते हैं। एक हैश मैप का उपयोग करें जहां कुंजियाँ सॉर्टेड शब्द हैं और मान मूल शब्दों की सरणियाँ हैं।

function groupAnagrams(strs) { const map = {}; for (const str of strs) { const sortedStr = str.split('').sort().join(''); if (!map[sortedStr]) { map[sortedStr] = []; } map[sortedStr].push(str); } return Object.values(map); } console.log(groupAnagrams(['eat', 'tea', 'tan', 'ate', 'nat', 'bat'])); // आउटपुट: [['eat', 'tea', 'ate'], ['tan', 'nat'], ['bat']]

शून्य को अंत तक ले जाएँ

एक सरणी nums दी गई है, सभी 0 को अंत तक ले जाने के लिए एक फ़ंक्शन लिखें, गैर-शून्य तत्वों के सापेक्ष क्रम को बनाए रखते हुए।

स्पष्टीकरण: 'दो-पॉइंटर' या 'स्नोबॉल' दृष्टिकोण का उपयोग करें। एक पॉइंटर उस स्थिति को ट्रैक करता है जहाँ अगला गैर-शून्य तत्व जाना चाहिए। सरणी के माध्यम से पुनरावृति करें; यदि कोई तत्व शून्य नहीं है, तो उसे पॉइंटर की स्थिति पर रखें और पॉइंटर को बढ़ाएँ। अंत में, शेष को शून्य से भरें।

function moveZeroes(nums) { let nonZeroIndex = 0; // सभी गैर-शून्य तत्वों को शुरुआत में ले जाएँ for (let i = 0; i < nums.length; i++) { if (nums[i] !== 0) { nums[nonZeroIndex] = nums[i]; nonZeroIndex++; } } // शेष को शून्य से भरें for (let i = nonZeroIndex; i < nums.length; i++) { nums[i] = 0; } return nums; } console.log(moveZeroes([0, 1, 0, 3, 12])); // [1, 3, 12, 0, 0]

अधिकतम सबएरे योग (कडाने का एल्गोरिथम)

पूर्णांकों की एक सरणी nums दी गई है, सन्निहित सबएरे (जिसमें कम से कम एक संख्या हो) ढूँढें जिसका योग सबसे बड़ा हो और उसका योग लौटाएँ।

स्पष्टीकरण: कडाने का एल्गोरिथम इसे हल करने का एक कुशल तरीका है। सरणी के माध्यम से पुनरावृति करें, वर्तमान स्थिति पर समाप्त होने वाले currentMax योग और अब तक पाए गए globalMax योग का ट्रैक रखें। यदि currentMax नकारात्मक हो जाता है, तो इसे 0 पर रीसेट करें (या बेहतर, वर्तमान तत्व पर)।

function maxSubArray(nums) { let globalMax = -Infinity; let currentMax = 0; for (let i = 0; i < nums.length; i++) { currentMax = Math.max(nums[i], currentMax + nums[i]); if (currentMax > globalMax) { globalMax = currentMax; } } return globalMax; } console.log(maxSubArray([-2, 1, -3, 4, -1, 2, 1, -5, 4])); // 6 ([4, -1, 2, 1] से)

एक स्ट्रिंग की क्रमपरिवर्तन

एक दी गई स्ट्रिंग के सभी क्रमपरिवर्तन उत्पन्न करने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: यह आमतौर पर पुनरावर्तन और बैकट्रैकिंग का उपयोग करके हल किया जाता है। प्रत्येक वर्ण के लिए, इसे ठीक करें और स्ट्रिंग के शेष के लिए क्रमपरिवर्तन को पुनरावर्ती रूप से उत्पन्न करें। आधार मामला: जब स्ट्रिंग में केवल एक वर्ण होता है, तो उसे लौटाएँ।

function stringPermutations(str) { if (str.length === 0) return ['']; if (str.length === 1) return [str]; const results = []; for (let i = 0; i < str.length; i++) { const char = str[i]; const remainingChars = str.slice(0, i) + str.slice(i + 1); const perms = stringPermutations(remainingChars); for (const perm of perms) { results.push(char + perm); } } return [...new Set(results)]; // यदि आवश्यक हो तो डुप्लिकेट वर्णों को संभालने के लिए Set का उपयोग करें } console.log(stringPermutations('abc')); // ['abc', 'acb', 'bac', 'bca', 'cab', 'cba'] console.log(stringPermutations('aab')); // ['aab', 'aba', 'baa']

सबसे बड़ा सामान्य भाजक (GCD)

दो संख्याओं का सबसे बड़ा सामान्य भाजक (GCD) खोजने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: यूक्लिड का एल्गोरिथम एक कुशल तरीका है। यदि b 0 है, तो a GCD है। अन्यथा, a और b का GCD b और a % b ( a को b से विभाजित करने का शेष) के GCD के समान है।

function gcd(a, b) { while (b !== 0) { let temp = b; b = a % b; a = temp; } return a; } console.log(gcd(48, 18)); // 6 console.log(gcd(101, 103)); // 1

न्यूनतम सामान्य गुणक (LCM)

दो संख्याओं का न्यूनतम सामान्य गुणक (LCM) खोजने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: LCM की गणना GCD का उपयोग करके सूत्र से की जा सकती है: LCM(a, b) = |a * b| / GCD(a, b)।

function gcd(a, b) { // पिछले समस्या का हेल्पर while (b !== 0) { let temp = b; b = a % b; a = temp; } return a; } function lcm(a, b) { if (a === 0 || b === 0) return 0; return Math.abs(a * b) / gcd(a, b); } console.log(lcm(15, 20)); // 60 console.log(lcm(7, 5)); // 35

Promise.all को लागू करें

Promise.all की तरह व्यवहार करने वाले एक फ़ंक्शन को लागू करें।

स्पष्टीकरण: Promise.all प्रतिज्ञाओं की एक सरणी लेता है और एक एकल प्रतिज्ञा लौटाता है जो तब हल हो जाती है जब सभी इनपुट प्रतिज्ञाएँ हल हो जाती हैं, या यदि कोई इनपुट प्रतिज्ञा अस्वीकार कर दी जाती है तो अस्वीकार कर दी जाती है। हल किया गया मान हल किए गए मानों की एक सरणी है।

function myPromiseAll(promises) { return new Promise((resolve, reject) => { const results = []; let completedCount = 0; const numPromises = promises.length; if (numPromises === 0) { resolve([]); return; } promises.forEach((promise, index) => { Promise.resolve(promise) .then(value => { results[index] = value; completedCount++; if (completedCount === numPromises) { resolve(results); } }) .catch(reject); // किसी भी त्रुटि पर तुरंत अस्वीकार करें }); }); } // उपयोग का उदाहरण: const p1 = Promise.resolve(3); const p2 = 42; const p3 = new Promise((resolve) => setTimeout(resolve, 100, 'foo')); myPromiseAll([p1, p2, p3]).then(values => console.log(values)); // [3, 42, 'foo']

बाइनरी ट्री को उलटना

एक बाइनरी ट्री को उलटने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: एक बाइनरी ट्री को उलटने के लिए, आप प्रत्येक नोड के बाएँ और दाएँ बच्चों को स्वैप करते हैं। यह पुनरावर्ती या पुनरावृत्ति (एक कतार या स्टैक का उपयोग करके) से किया जा सकता है।

class Node { constructor(val, left = null, right = null) { this.val = val; this.left = left; this.right = right; } } function invertTree(root) { if (root === null) { return null; } // बच्चों को स्वैप करें [root.left, root.right] = [root.right, root.left]; // बाएँ और दाएँ बच्चों को पुनरावर्ती रूप से पार करें invertTree(root.left); invertTree(root.right); return root; } // उदाहरण: 4 -> [2, 7] -> [1, 3, 6, 9] // इसमें परिवर्तित होता है: 4 -> [7, 2] -> [9, 6, 3, 1]

एक बाइनरी ट्री की अधिकतम गहराई

एक बाइनरी ट्री दिया गया है, इसकी अधिकतम गहराई ज्ञात करें।

स्पष्टीकरण: अधिकतम गहराई रूट नोड से सबसे दूर के लीफ नोड तक के सबसे लंबे पथ के साथ नोड्स की संख्या है। इसे पुनरावर्ती रूप से पाया जा सकता है: MaxDepth = 1 + max(MaxDepth(left), MaxDepth(right))। आधार मामला तब होता है जब एक नोड शून्य होता है, इसकी गहराई 0 होती है।

class Node { constructor(val, left = null, right = null) { this.val = val; this.left = left; this.right = right; } } function maxDepth(root) { if (root === null) { return 0; } const leftDepth = maxDepth(root.left); const rightDepth = maxDepth(root.right); return Math.max(leftDepth, rightDepth) + 1; } // उदाहरण: 3 -> [9, 20] -> [null, null, 15, 7] const tree = new Node(3, new Node(9), new Node(20, new Node(15), new Node(7))); console.log(maxDepth(tree)); // 3

स्टॉक खरीदने/बेचने का सबसे अच्छा समय

आपको एक सरणी prices दी गई है जहाँ prices[i] दिन i पर किसी दिए गए स्टॉक की कीमत है। आप एक स्टॉक खरीदने के लिए एक दिन और उस स्टॉक को बेचने के लिए भविष्य में एक अलग दिन चुनकर अपना लाभ अधिकतम करना चाहते हैं। अधिकतम लाभ लौटाएँ।

स्पष्टीकरण: कीमतों के माध्यम से पुनरावृति करें, अब तक मिली न्यूनतम कीमत (minPrice) और अब तक मिले अधिकतम लाभ (maxProfit) का ट्रैक रखें। प्रत्येक दिन के लिए, संभावित लाभ की गणना करें यदि आप आज बेचते हैं (वर्तमान कीमत - minPrice) और यदि यह अधिक है तो maxProfit को अपडेट करें।

function maxProfit(prices) { let minPrice = Infinity; let maxProfit = 0; for (let i = 0; i < prices.length; i++) { if (prices[i] < minPrice) { minPrice = prices[i]; } else if (prices[i] - minPrice > maxProfit) { maxProfit = prices[i] - minPrice; } } return maxProfit; } console.log(maxProfit([7, 1, 5, 3, 6, 4])); // 5 (1 पर खरीदें, 6 पर बेचें) console.log(maxProfit([7, 6, 4, 3, 1])); // 0 (लाभ प्राप्त करना संभव नहीं है)

अद्वितीय संख्या

पूर्णांकों nums की एक गैर-खाली सरणी दी गई है, प्रत्येक तत्व दो बार प्रकट होता है सिवाय एक के। उस अद्वितीय तत्व को ढूँढें।

स्पष्टीकरण: इसे हल करने का एक बहुत ही कुशल तरीका बिटवाइज़ XOR (^) ऑपरेटर का उपयोग करना है। एक संख्या को स्वयं से XOR करने पर 0 परिणाम होता है। एक संख्या को 0 से XOR करने पर वही संख्या परिणाम होती है। यदि आप सरणी में सभी संख्याओं को XOR करते हैं, तो जोड़े रद्द हो जाएंगे (0 बन जाएंगे), केवल अद्वितीय संख्या बचेगी।

function singleNumber(nums) { let result = 0; for (const num of nums) { result ^= num; } return result; } console.log(singleNumber([2, 2, 1])); // 1 console.log(singleNumber([4, 1, 2, 1, 2])); // 4

बहुसंख्यक तत्व

n आकार की एक सरणी nums दी गई है, बहुसंख्यक तत्व लौटाएँ। बहुसंख्यक तत्व वह तत्व है जो ⌊n / 2⌋ से अधिक बार प्रकट होता है।

स्पष्टीकरण: बोयर-मूर वोटिंग एल्गोरिथम एक कुशल तरीका है। एक उम्मीदवार और एक काउंटर को इनिशियलाइज़ करें। सरणी के माध्यम से पुनरावृति करें। यदि काउंटर 0 है, तो वर्तमान तत्व को उम्मीदवार के रूप में सेट करें। यदि वर्तमान तत्व उम्मीदवार से मेल खाता है, तो काउंटर बढ़ाएँ; अन्यथा, काउंटर घटाएँ।

function majorityElement(nums) { let candidate = null; let count = 0; for (const num of nums) { if (count === 0) { candidate = num; } count += (num === candidate) ? 1 : -1; } return candidate; } console.log(majorityElement([3, 2, 3])); // 3 console.log(majorityElement([2, 2, 1, 1, 1, 2, 2])); // 2

सीढ़ियाँ चढ़ना

आप एक सीढ़ी चढ़ रहे हैं। शीर्ष पर पहुँचने के लिए n कदम लगते हैं। हर बार आप 1 या 2 कदम चढ़ सकते हैं। आप शीर्ष पर कितने अलग-अलग तरीकों से चढ़ सकते हैं?

स्पष्टीकरण: यह एक क्लासिक डायनेमिक प्रोग्रामिंग समस्या है, जो फाइबोनैचि अनुक्रम के बहुत समान है। n कदम तक पहुँचने के तरीकों की संख्या n-1 कदम तक पहुँचने के तरीकों (1 कदम लेने) और n-2 कदम तक पहुँचने के तरीकों (2 कदम लेने) का योग है। dp[n] = dp[n-1] + dp[n-2]

function climbStairs(n) { if (n <= 2) return n; let oneStepBefore = 2; let twoStepsBefore = 1; let allWays = 0; for (let i = 3; i <= n; i++) { allWays = oneStepBefore + twoStepsBefore; twoStepsBefore = oneStepBefore; oneStepBefore = allWays; } return allWays; } console.log(climbStairs(2)); // 2 (1+1, 2) console.log(climbStairs(3)); // 3 (1+1+1, 1+2, 2+1) console.log(climbStairs(4)); // 5

स्वयं को छोड़कर सरणी का उत्पाद

पूर्णांकों nums की एक सरणी दी गई है, एक सरणी answer लौटाएँ जैसे कि answer[i] nums[i] को छोड़कर nums के सभी तत्वों के उत्पाद के बराबर हो। विभाजन ऑपरेटर का उपयोग न करें।

स्पष्टीकरण: आप उपसर्ग उत्पादों और प्रत्यय उत्पादों की गणना करके इसे हल कर सकते हैं। सूचकांक i पर परिणाम i से पहले के सभी तत्वों का उत्पाद है जिसे i के बाद के सभी तत्वों के उत्पाद से गुणा किया गया है।

function productExceptSelf(nums) { const n = nums.length; const answer = new Array(n).fill(1); // उपसर्ग उत्पादों की गणना करें let prefix = 1; for (let i = 0; i < n; i++) { answer[i] = prefix; prefix *= nums[i]; } // प्रत्यय उत्पादों की गणना करें और उपसर्ग के साथ गुणा करें let suffix = 1; for (let i = n - 1; i >= 0; i--) { answer[i] *= suffix; suffix *= nums[i]; } return answer; } console.log(productExceptSelf([1, 2, 3, 4])); // [24, 12, 8, 6]

द्वीपों की संख्या

'1's (भूमि) और '0's (पानी) की एक 2D ग्रिड दी गई है, द्वीपों की संख्या की गणना करें। एक द्वीप पानी से घिरा हुआ है और आसन्न भूमि को क्षैतिज या लंबवत रूप से जोड़कर बनता है।

स्पष्टीकरण: ग्रिड की प्रत्येक सेल के माध्यम से पुनरावृति करें। यदि आपको '1' (भूमि) मिलता है, तो द्वीप काउंटर बढ़ाएँ और उस सेल से एक गहराई-पहली खोज (DFS) या चौड़ाई-पहली खोज (BFS) शुरू करें। खोज के दौरान, सभी जुड़े '1's को '0' (या विज़िट किया गया) के रूप में चिह्नित करें ताकि उन्हें फिर से गिनने से बचा जा सके।

function numIslands(grid) { if (!grid || grid.length === 0) return 0; let count = 0; const rows = grid.length; const cols = grid[0].length; function dfs(r, c) { if (r < 0 || c < 0 || r >= rows || c >= cols || grid[r][c] === '0') { return; } grid[r][c] = '0'; // विज़िट के रूप में चिह्नित करें dfs(r + 1, c); dfs(r - 1, c); dfs(r, c + 1); dfs(r, c - 1); } for (let r = 0; r < rows; r++) { for (let c = 0; c < cols; c++) { if (grid[r][c] === '1') { count++; dfs(r, c); } } } return count; } const grid1 = [ ['1', '1', '1', '1', '0'], ['1', '1', '0', '1', '0'], ['1', '1', '0', '0', '0'], ['0', '0', '0', '0', '0'] ]; // console.log(numIslands(grid1)); // 1 (एक कॉपी पर चलने या ग्रिड को पुनर्स्थापित करने की आवश्यकता है)

LRU कैश

एक लीस्ट रिसेंटली यूज्ड (LRU) कैश के लिए एक डेटा संरचना डिज़ाइन और लागू करें। इसे get और put संचालन का समर्थन करना चाहिए।

स्पष्टीकरण: एक LRU कैश सबसे कम हाल ही में उपयोग किए गए तत्व को बाहर निकाल देता है जब क्षमता पहुँच जाती है। एक सामान्य कार्यान्वयन औसत समय में O(1) लुकअप के लिए एक Map (या एक हैश मैप) और 'हाल ही में उपयोग किए गए' स्थिति के O(1) अपडेट के लिए एक डबल लिंक्ड सूची का उपयोग करता है। जावास्क्रिप्ट का Map सम्मिलन क्रम को बनाए रखता है, जो एक बुनियादी कार्यान्वयन को सरल बना सकता है।

class LRUCache { constructor(capacity) { this.capacity = capacity; this.cache = new Map(); } get(key) { if (!this.cache.has(key)) return -1; const value = this.cache.get(key); this.cache.delete(key); // 'अंत' (सबसे हाल ही में) में फिर से डालने के लिए हटाएँ this.cache.set(key, value); return value; } put(key, value) { if (this.cache.has(key)) { this.cache.delete(key); } else if (this.cache.size >= this.capacity) { const oldestKey = this.cache.keys().next().value; this.cache.delete(oldestKey); } this.cache.set(key, value); } } const cache = new LRUCache(2); cache.put(1, 1); cache.put(2, 2); console.log(cache.get(1)); // 1 cache.put(3, 3); // 2 को बाहर निकालता है console.log(cache.get(2)); // -1

कोष्ठक उत्पन्न करें

n जोड़े कोष्ठक दिए गए हैं, सुव्यवस्थित कोष्ठक के सभी संयोजनों को उत्पन्न करने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: यह एक क्लासिक बैकट्रैकिंग समस्या है। खुले और बंद कोष्ठक की संख्या बनाए रखें। यदि open < n है तो आप एक खुला कोष्ठक जोड़ सकते हैं। यदि close < open है तो आप एक बंद कोष्ठक जोड़ सकते हैं। आधार मामला तब होता है जब स्ट्रिंग की लंबाई 2 * n तक पहुँच जाती है।

function generateParenthesis(n) { const results = []; function backtrack(currentString, openCount, closeCount) { if (currentString.length === n * 2) { results.push(currentString); return; } if (openCount < n) { backtrack(currentString + '(', openCount + 1, closeCount); } if (closeCount < openCount) { backtrack(currentString + ')', openCount, closeCount + 1); } } backtrack('', 0, 0); return results; } console.log(generateParenthesis(3)); // ['((()))', '(()())', '(())()', '()(())', '()()()']

सबसे अधिक पानी वाला कंटेनर

n गैर-ऋणात्मक पूर्णांक a1, a2, ..., an दिए गए हैं, जहाँ प्रत्येक (i, ai) निर्देशांक पर एक बिंदु का प्रतिनिधित्व करता है। n ऊर्ध्वाधर रेखाएँ इस प्रकार खींची जाती हैं कि रेखा i के दो अंतिम बिंदु (i, ai) और (i, 0) पर हैं। दो रेखाएँ ढूँढें जो, x-अक्ष के साथ मिलकर, एक कंटेनर बनाती हैं, जिससे कंटेनर में सबसे अधिक पानी हो।

स्पष्टीकरण: दो-पॉइंटर दृष्टिकोण का उपयोग करें। एक पॉइंटर के साथ शुरू में और दूसरा अंत में। क्षेत्र की गणना करें। क्षेत्र सबसे छोटी रेखा द्वारा सीमित है। संभावित रूप से एक बड़े क्षेत्र को खोजने के लिए, उस पॉइंटर को अंदर ले जाएँ जो सबसे छोटी रेखा की ओर इशारा कर रहा है।

function maxArea(height) { let max = 0; let left = 0; let right = height.length - 1; while (left < right) { const h = Math.min(height[left], height[right]); const w = right - left; max = Math.max(max, h * w); if (height[left] < height[right]) { left++; } else { right--; } } return max; } console.log(maxArea([1, 8, 6, 2, 5, 4, 8, 3, 7])); // 49

3Sum

n पूर्णांकों की एक सरणी nums दी गई है, क्या nums में a, b, c तत्व ऐसे हैं कि a + b + c = 0? सरणी में सभी अद्वितीय तिकड़ियों को ढूँढें जिनका योग शून्य हो।

स्पष्टीकरण: सबसे पहले, सरणी को सॉर्ट करें। फिर, एक पॉइंटर i के साथ सरणी के माध्यम से पुनरावृति करें। प्रत्येक i के लिए, दो और पॉइंटर, left (i+1 से शुरू) और right (अंत से शुरू), का उपयोग करके दो संख्याएँ ढूँढें जिनका योग -nums[i] हो। अद्वितीय तिकड़ियों को सुनिश्चित करने के लिए डुप्लिकेट को संभालें।

function threeSum(nums) { nums.sort((a, b) => a - b); const results = []; for (let i = 0; i < nums.length - 2; i++) { if (i > 0 && nums[i] === nums[i - 1]) continue; // i के लिए डुप्लिकेट छोड़ें let left = i + 1; let right = nums.length - 1; let target = -nums[i]; while (left < right) { let sum = nums[left] + nums[right]; if (sum === target) { results.push([nums[i], nums[left], nums[right]]); while (left < right && nums[left] === nums[left + 1]) left++; // डुप्लिकेट छोड़ें while (left < right && nums[right] === nums[right - 1]) right--; // डुप्लिकेट छोड़ें left++; right--; } else if (sum < target) { left++; } else { right--; } } } return results; } console.log(threeSum([-1, 0, 1, 2, -1, -4])); // [[-1, -1, 2], [-1, 0, 1]]

खोज सम्मिलन स्थिति

विशिष्ट पूर्णांकों की एक सॉर्टेड सरणी और एक लक्ष्य मान दिया गया है, यदि लक्ष्य पाया जाता है तो सूचकांक लौटाएँ। यदि नहीं, तो वह सूचकांक लौटाएँ जहाँ इसे क्रम में डाला जाएगा।

स्पष्टीकरण: यह बाइनरी खोज का एक भिन्नरूप है। बाइनरी खोज करें, लेकिन यदि तत्व नहीं मिलता है, तो start पॉइंटर उस स्थिति पर समाप्त होगा जहाँ तत्व डाला जाना चाहिए।

function searchInsert(nums, target) { let start = 0; let end = nums.length - 1; while (start <= end) { let mid = Math.floor((start + end) / 2); if (nums[mid] === target) { return mid; } else if (nums[mid] < target) { start = mid + 1; } else { end = mid - 1; } } return start; // यदि नहीं मिला, तो start सम्मिलन बिंदु है } console.log(searchInsert([1, 3, 5, 6], 5)); // 2 console.log(searchInsert([1, 3, 5, 6], 2)); // 1 console.log(searchInsert([1, 3, 5, 6], 7)); // 4

दो सॉर्ट की गई सूचियों को मर्ज करें (लिंक्ड सूचियाँ)

दो सॉर्ट की गई लिंक्ड सूचियों को मर्ज करें और इसे एक नई सॉर्ट की गई सूची के रूप में लौटाएँ। नई सूची को पहली दो सूचियों के नोड्स को स्प्लिस करके बनाया जाना चाहिए।

स्पष्टीकरण: प्रक्रिया को सरल बनाने के लिए एक डमी हेड नोड का उपयोग करें। नई सूची बनाने के लिए एक पॉइंटर का उपयोग करें। दोनों इनपुट सूचियों के वर्तमान नोड्स की तुलना करें और छोटे वाले को नई सूची में जोड़ें, उस सूची के पॉइंटर को आगे बढ़ाएँ। तब तक दोहराएँ जब तक एक सूची समाप्त न हो जाए, फिर दूसरी सूची का शेष जोड़ें।

class ListNode { constructor(val = 0, next = null) { this.val = val; this.next = next; } } function mergeTwoLists(l1, l2) { let dummyHead = new ListNode(); let current = dummyHead; while (l1 !== null && l2 !== null) { if (l1.val < l2.val) { current.next = l1; l1 = l1.next; } else { current.next = l2; l2 = l2.next; } current = current.next; } current.next = l1 !== null ? l1 : l2; return dummyHead.next; } // उदाहरण: 1->2->4 और 1->3->4 => 1->1->2->3->4->4

सममित ट्री

एक बाइनरी ट्री दिया गया है, जाँच करें कि क्या यह स्वयं का दर्पण है (यानी, इसके केंद्र के चारों ओर सममित)।

स्पष्टीकरण: इसे पुनरावर्ती रूप से हल किया जा सकता है। एक ट्री सममित होता है यदि बाएँ सबट्री दाएँ सबट्री की एक दर्पण छवि है। एक सहायक फ़ंक्शन isMirror(t1, t2) बनाएँ जो जाँचता है कि क्या दो ट्री दर्पण हैं। इसे जाँच करनी चाहिए: 1. t1.val === t2.val। 2. t1.left t2.right का दर्पण है। 3. t1.right t2.left का दर्पण है।

class Node { constructor(val, left = null, right = null) { this.val = val; this.left = left; this.right = right; } } function isSymmetric(root) { if (!root) return true; function isMirror(t1, t2) { if (!t1 && !t2) return true; if (!t1 || !t2 || t1.val !== t2.val) return false; return isMirror(t1.left, t2.right) && isMirror(t1.right, t2.left); } return isMirror(root.left, root.right); } // उदाहरण: 1 -> [2, 2] -> [3, 4, 4, 3] सममित है।

स्तर-वार ट्रैवर्सल (BST/ट्री)

एक बाइनरी ट्री दिया गया है, इसके नोड मानों का स्तर-वार ट्रैवर्सल लौटाएँ (यानी, बाएँ से दाएँ, स्तर दर स्तर)।

स्पष्टीकरण: यह एक चौड़ाई-पहली खोज (BFS) है। एक कतार का उपयोग करें। कतार में रूट जोड़कर शुरू करें। जब तक कतार खाली न हो, वर्तमान स्तर के सभी नोड्स को संसाधित करें। संसाधित प्रत्येक नोड के लिए, उसके बच्चों (यदि मौजूद हों) को अगले स्तर के लिए कतार में जोड़ें।

class Node { constructor(val, left = null, right = null) { this.val = val; this.left = left; this.right = right; } } function levelOrder(root) { if (!root) return []; const result = []; const queue = [root]; while (queue.length > 0) { const levelSize = queue.length; const currentLevel = []; for (let i = 0; i < levelSize; i++) { const node = queue.shift(); currentLevel.push(node.val); if (node.left) queue.push(node.left); if (node.right) queue.push(node.right); } result.push(currentLevel); } return result; } // उदाहरण: 3 -> [9, 20] -> [null, null, 15, 7] // आउटपुट: [[3], [9, 20], [15, 7]]

सॉर्टेड सरणी को ऊँचाई-संतुलित BST में बदलें

एक सरणी दी गई है जहाँ तत्व आरोही क्रम में सॉर्ट किए गए हैं, इसे एक ऊँचाई-संतुलित बाइनरी सर्च ट्री (BST) में बदलें।

स्पष्टीकरण: एक ऊँचाई-संतुलित BST बनाने के लिए, आपको सरणी के मध्य तत्व को रूट के रूप में चुनना होगा। फिर, सरणी के बाएँ आधे से बाएँ सबट्री और दाएँ आधे से दाएँ सबट्री का पुनरावर्ती रूप से निर्माण करें।

class TreeNode { constructor(val = 0, left = null, right = null) { this.val = val; this.left = left; this.right = right; } } function sortedArrayToBST(nums) { if (!nums || nums.length === 0) return null; function buildBST(start, end) { if (start > end) return null; const mid = Math.floor((start + end) / 2); const node = new TreeNode(nums[mid]); node.left = buildBST(start, mid - 1); node.right = buildBST(mid + 1, end); return node; } return buildBST(0, nums.length - 1); } // उदाहरण: [-10, -3, 0, 5, 9] // आउटपुट: [0, -3, 9, -10, null, 5, null] जैसा एक ट्री

`bind` को लागू करें

Function.prototype.bind के अपने स्वयं के संस्करण को लागू करें।

स्पष्टीकरण: bind एक नया फ़ंक्शन बनाता है, जिसे जब बुलाया जाता है, तो उसका this कीवर्ड प्रदान किए गए मान पर सेट होता है, जिसमें तर्कों का एक दिया गया अनुक्रम नई फ़ंक्शन को बुलाए जाने पर प्रदान किए गए किसी भी तर्क से पहले होता है। आंशिक अनुप्रयोग (पूर्व-निर्धारित तर्क) को संभालते हुए, एक लौटाए गए फ़ंक्शन के भीतर apply या call का उपयोग करें।

Function.prototype.myBind = function(context, ...bindArgs) { const originalFunc = this; return function(...callArgs) { return originalFunc.apply(context, [...bindArgs, ...callArgs]); }; } const module = { x: 42, getX: function() { return this.x; } }; const unboundGetX = module.getX; console.log(unboundGetX()); // undefined (this वैश्विक/विंडो है) const boundGetX = unboundGetX.myBind(module); console.log(boundGetX()); // 42

के-वां सबसे बड़ा तत्व ढूँढें

एक अनसॉर्टेड सरणी में के-वां सबसे बड़ा तत्व ढूँढें। ध्यान दें कि यह सॉर्ट किए गए क्रम में के-वां सबसे बड़ा तत्व है, न कि के-वां अलग तत्व।

स्पष्टीकरण: एक सरल दृष्टिकोण सरणी को सॉर्ट करना और फिर n - k सूचकांक पर तत्व लेना है। बड़ी सरणियों के लिए एक अधिक कुशल दृष्टिकोण एक मिन-हीप या क्विकसेलेक्ट जैसे चयन एल्गोरिथम का उपयोग करना शामिल है।

function findKthLargest(nums, k) { // सरल दृष्टिकोण: सॉर्ट करें nums.sort((a, b) => b - a); // अवरोही क्रम में सॉर्ट करें return nums[k - 1]; // नोट: क्विकसेलेक्ट एक साक्षात्कार में अधिक कुशल होगा // लेकिन सॉर्टिंग जल्दी लागू करना आसान है। } console.log(findKthLargest([3, 2, 1, 5, 6, 4], 2)); // 5 console.log(findKthLargest([3, 2, 3, 1, 2, 4, 5, 5, 6], 4)); // 4

जाँच करें कि क्या किसी ऑब्जेक्ट में एक गुण है

आप कैसे जाँच सकते हैं कि किसी ऑब्जेक्ट में एक विशिष्ट गुण है या नहीं?

स्पष्टीकरण: आप in ऑपरेटर (अपने और विरासत में मिले गुणों की जाँच करता है), Object.prototype.hasOwnProperty.call(obj, prop) (केवल अपने गुणों की जाँच करता है), या बस obj.prop !== undefined ( undefined मानों के साथ मुश्किल हो सकता है) का उपयोग कर सकते हैं।

const person = { name: 'Eve', age: 28 }; function hasProp(obj, prop) { console.log(`'in' का उपयोग करके: ${prop in obj}`); console.log(`'hasOwnProperty' का उपयोग करके: ${Object.prototype.hasOwnProperty.call(obj, prop)}`); } hasProp(person, 'name'); // true, true hasProp(person, 'toString'); // true, false (toString विरासत में मिला है)

पूर्णांक से रोमन

एक पूर्णांक को उसके रोमन संख्या प्रतिनिधित्व में बदलने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: रोमन संख्याओं और उनके संबंधित मानों का एक मानचित्र बनाएँ, बड़े से छोटे तक सॉर्ट किया गया। इस मानचित्र के माध्यम से पुनरावृति करें। प्रत्येक मान के लिए, इसे इनपुट संख्या से जितनी बार संभव हो उतनी बार घटाएँ, हर बार रोमन संख्या जोड़ते हुए।

function intToRoman(num) { const map = { M: 1000, CM: 900, D: 500, CD: 400, C: 100, XC: 90, L: 50, XL: 40, X: 10, IX: 9, V: 5, IV: 4, I: 1 }; let result = ''; for (let key in map) { while (num >= map[key]) { result += key; num -= map[key]; } } return result; } console.log(intToRoman(3)); // III console.log(intToRoman(58)); // LVIII console.log(intToRoman(1994)); // MCMXCIV

रोमन से पूर्णांक

एक रोमन संख्या को एक पूर्णांक में बदलने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: रोमन प्रतीकों से मानों का एक मानचित्र बनाएँ। स्ट्रिंग के माध्यम से पुनरावृति करें। यदि वर्तमान प्रतीक का मान अगले प्रतीक के मान से कम है (जैसे 'IV' या 'IX'), तो वर्तमान मान घटाएँ; अन्यथा, इसे जोड़ें।

function romanToInt(s) { const map = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 }; let result = 0; for (let i = 0; i < s.length; i++) { const currentVal = map[s[i]]; const nextVal = map[s[i + 1]]; if (nextVal > currentVal) { result -= currentVal; } else { result += currentVal; } } return result; } console.log(romanToInt('III')); // 3 console.log(romanToInt('LVIII')); // 58 console.log(romanToInt('MCMXCIV')); // 1994

एक `Set` को लागू करें

add, has, delete और size विधियों के साथ एक बुनियादी Set डेटा संरचना (निर्मित Set का उपयोग किए बिना) को लागू करें।

स्पष्टीकरण: आप एक जावास्क्रिप्ट ऑब्जेक्ट (हैश मैप) को अंतर्निहित स्टोरेज के रूप में उपयोग कर सकते हैं। कुंजियाँ सेट के तत्व होंगी (आपको विभिन्न प्रकारों को कैसे स्टोर करना है और कुंजियों के रूप में विशिष्टता सुनिश्चित करनी है, इसे संभालने की आवश्यकता हो सकती है)।

class MySet { constructor() { this.items = {}; this._size = 0; } add(element) { if (!this.has(element)) { this.items[element] = element; // तत्व को स्टोर करें this._size++; return true; } return false; } delete(element) { if (this.has(element)) { delete this.items[element]; this._size--; return true; } return false; } has(element) { return Object.prototype.hasOwnProperty.call(this.items, element); } get size() { return this._size; } } const set = new MySet(); set.add(1); set.add(2); console.log(set.has(1)); // true console.log(set.size); // 2 set.delete(1); console.log(set.has(1)); // false

पास्कल का त्रिभुज

एक पूर्णांक numRows को देखते हुए, पास्कल के त्रिभुज की पहली numRows पंक्तियाँ उत्पन्न करें।

स्पष्टीकरण: पास्कल के त्रिभुज में, प्रत्येक संख्या उसके ठीक ऊपर की दो संख्याओं का योग होती है। यह [[1]] से शुरू होता है। प्रत्येक बाद की पंक्ति के लिए, यह 1 से शुरू और समाप्त होती है। प्रत्येक मध्य तत्व उसी सूचकांक पर तत्व और ऊपर की पंक्ति के पिछले सूचकांक पर तत्व का योग होता है।

function generatePascalsTriangle(numRows) { if (numRows === 0) return []; const triangle = [[1]]; for (let i = 1; i < numRows; i++) { const prevRow = triangle[i - 1]; const newRow = [1]; for (let j = 1; j < i; j++) { newRow.push(prevRow[j - 1] + prevRow[j]); } newRow.push(1); triangle.push(newRow); } return triangle; } console.log(generatePascalsTriangle(5)); // [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]

शब्द खोज

एक 2D बोर्ड और एक शब्द को देखते हुए, पता लगाएं कि शब्द ग्रिड में मौजूद है या नहीं। शब्द को क्रमिक रूप से आसन्न कोशिकाओं के अक्षरों से बनाया जा सकता है, जहां 'आसन्न' कोशिकाएँ क्षैतिज या लंबवत रूप से पड़ोसी होती हैं।

स्पष्टीकरण: इसके लिए बैकट्रैकिंग के साथ गहराई-पहली खोज (DFS) की आवश्यकता है। प्रत्येक कोशिका के माध्यम से पुनरावृति करें। यदि कोई कोशिका शब्द के पहले अक्षर से मेल खाती है, तो DFS शुरू करें। DFS फ़ंक्शन पड़ोसी कोशिकाओं की जाँच करता है, यह सुनिश्चित करता है कि वे अगले अक्षर से मेल खाते हैं और वर्तमान पथ में उनका दौरा नहीं किया गया है। यदि कोई पथ विफल हो जाता है, तो कोशिका को अनमार्क करके बैकट्रैक करें।

function exist(board, word) { const rows = board.length; const cols = board[0].length; function dfs(r, c, index) { if (index === word.length) return true; // शब्द मिल गया if (r < 0 || c < 0 || r >= rows || c >= cols || board[r][c] !== word[index]) { return false; } const temp = board[r][c]; board[r][c] = '#'; // दौरा किया गया चिह्नित करें const found = dfs(r + 1, c, index + 1) || dfs(r - 1, c, index + 1) || dfs(r, c + 1, index + 1) || dfs(r, c - 1, index + 1); board[r][c] = temp; // बैकट्रैक return found; } for (let r = 0; r < rows; r++) { for (let c = 0; c < cols; c++) { if (board[r][c] === word[0] && dfs(r, c, 0)) { return true; } } } return false; } const board = [['A','B','C','E'],['S','F','C','S'],['A','D','E','E']]; console.log(exist(board, 'ABCCED')); // true console.log(exist(board, 'SEE')); // true console.log(exist(board, 'ABCB')); // false

न्यूनतम विंडो सबस्ट्रिंग

दो स्ट्रिंग्स s और t को देखते हुए, s में न्यूनतम विंडो ढूंढें जिसमें t में सभी वर्ण शामिल होंगे। यदि s में ऐसी कोई विंडो नहीं है जो t में सभी वर्णों को कवर करती है, तो खाली स्ट्रिंग "" लौटाएँ।

स्पष्टीकरण: दो पॉइंटर्स (left और right) और हैश मैप्स के साथ एक स्लाइडिंग विंडो दृष्टिकोण का उपयोग करें। एक मैप t से आवश्यक वर्णों की गणना संग्रहीत करता है। एक और मैप वर्तमान विंडो में गणना संग्रहीत करता है। right के साथ विंडो का विस्तार करें। एक बार जब विंडो में सभी आवश्यक वर्ण शामिल हो जाते हैं, तो न्यूनतम संभव विंडो खोजने के लिए left के साथ इसे छोटा करने का प्रयास करें।

function minWindow(s, t) { if (!t || !s || s.length < t.length) return ""; const tMap = {}; for (const char of t) tMap[char] = (tMap[char] || 0) + 1; let required = Object.keys(tMap).length; let formed = 0; const windowMap = {}; let left = 0; let minLen = Infinity; let result = ""; for (let right = 0; right < s.length; right++) { const char = s[right]; windowMap[char] = (windowMap[char] || 0) + 1; if (tMap[char] && windowMap[char] === tMap[char]) { formed++; } while (left <= right && formed === required) { if (right - left + 1 < minLen) { minLen = right - left + 1; result = s.substring(left, right + 1); } const leftChar = s[left]; windowMap[leftChar]--; if (tMap[leftChar] && windowMap[leftChar] < tMap[leftChar]) { formed--; } left++; } } return result; } console.log(minWindow('ADOBECODEBANC', 'ABC')); // 'BANC'

लिंक्ड सूची को उलटना

एक एकल लिंक्ड सूची के head को देखते हुए, सूची को उलटा करें और उलटी हुई सूची लौटाएँ।

स्पष्टीकरण: आपको सूची के माध्यम से पुनरावृति करनी होगी, प्रत्येक नोड के next पॉइंटर को बदलने के लिए ताकि वह पिछले नोड को इंगित करे। पुनरावृति के दौरान previous, current और next नोड्स का ट्रैक रखें।

class ListNode { constructor(val = 0, next = null) { this.val = val; this.next = next; } } function reverseList(head) { let prev = null; let current = head; let next = null; while (current !== null) { next = current.next; // अगले नोड को संग्रहीत करें current.next = prev; // वर्तमान नोड के पॉइंटर को उलटा करें prev = current; // prev को एक कदम आगे बढ़ाएँ current = next; // current को एक कदम आगे बढ़ाएँ } return prev; // नया हेड अंतिम 'prev' है } // उदाहरण: 1->2->3->4->5 5->4->3->2->1 बन जाता है

लिंक्ड सूची में चक्र का पता लगाएं

head को देखते हुए, एक लिंक्ड सूची का head, निर्धारित करें कि लिंक्ड सूची में एक चक्र है या नहीं।

स्पष्टीकरण: 'फ्लॉयड का कछुआ और खरगोश' एल्गोरिथम का उपयोग करें। दो पॉइंटर रखें, एक जो एक बार में एक कदम चलता है (slow) और दूसरा जो एक बार में दो कदम चलता है (fast)। यदि कोई चक्र है, तो fast पॉइंटर अंततः slow पॉइंटर तक पहुंच जाएगा।

class ListNode { constructor(val = 0, next = null) { this.val = val; this.next = next; } } function hasCycle(head) { if (!head || !head.next) return false; let slow = head; let fast = head.next; while (slow !== fast) { if (!fast || !fast.next) return false; // अंत तक पहुँच गया, कोई चक्र नहीं slow = slow.next; fast = fast.next.next; } return true; // पॉइंटर मिल गए, एक चक्र मौजूद है } // उदाहरण: 3->2->0->-4, जिसमें -4 वापस 2 को इंगित करता है। hasCycle true लौटाता है।

`Object.create` लागू करें

एक फ़ंक्शन लागू करें जो Object.create(proto) के व्यवहार की नकल करता है।

स्पष्टीकरण: Object.create एक नई वस्तु बनाता है, एक मौजूदा वस्तु का उपयोग नई बनाई गई वस्तु के प्रोटोटाइप के रूप में करता है। आप इसे एक अस्थायी कंस्ट्रक्टर फ़ंक्शन बनाकर, उसके प्रोटोटाइप को इनपुट proto पर सेट करके, और फिर उसका एक नया इंस्टेंस लौटाकर प्राप्त कर सकते हैं।

function myObjectCreate(proto) { if (typeof proto !== 'object' && typeof proto !== 'function') { if (proto !== null) { throw new TypeError('Object prototype may only be an Object or null: ' + proto); } } function F() {} F.prototype = proto; return new F(); } const person = { isHuman: false, printIntroduction: function() { console.log(`मेरा नाम ${this.name} है। क्या मैं इंसान हूँ? ${this.isHuman}`); } }; const me = myObjectCreate(person); me.name = 'मैथ्यू'; me.isHuman = true; me.printIntroduction(); // मेरा नाम मैथ्यू है। क्या मैं इंसान हूँ? true console.log(Object.getPrototypeOf(me) === person); // true

होइस्टिंग क्या है?

जावास्क्रिप्ट में होइस्टिंग की व्याख्या करें और एक उदाहरण प्रदान करें।

स्पष्टीकरण: होइस्टिंग जावास्क्रिप्ट का डिफ़ॉल्ट व्यवहार है जिसमें घोषणाओं को कोड के निष्पादन से पहले वर्तमान स्कोप (वैश्विक या फ़ंक्शन) के शीर्ष पर ले जाया जाता है। चर घोषणाओं (var) को होइस्ट किया जाता है और undefined के साथ आरंभ किया जाता है। फ़ंक्शन घोषणाओं को पूरी तरह से होइस्ट किया जाता है (नाम और बॉडी दोनों)। let और const को होइस्ट किया जाता है लेकिन आरंभ नहीं किया जाता है, जिससे एक अस्थायी डेड ज़ोन होता है।

console.log(myVar); // undefined (var को होइस्ट किया जाता है और undefined के साथ आरंभ किया जाता है) // console.log(myLet); // ReferenceError: Cannot access 'myLet' before initialization (TDZ) myFunc(); // 'नमस्ते!' (फ़ंक्शन घोषणा पूरी तरह से होइस्ट हो जाती है) var myVar = 'मैं एक var हूँ'; let myLet = 'मैं एक let हूँ'; function myFunc() { console.log('नमस्ते!'); }

इवेंट बबलिंग और कैप्चरिंग की व्याख्या करें

DOM के संदर्भ में इवेंट बबलिंग और कैप्चरिंग की व्याख्या करें।

स्पष्टीकरण: ये HTML DOM में इवेंट प्रसार के दो चरण हैं। कैप्चरिंग चरण: इवेंट window से लक्ष्य तत्व तक यात्रा करता है। बबलिंग चरण: इवेंट लक्ष्य तत्व से वापस window तक यात्रा करता है। डिफ़ॉल्ट रूप से, अधिकांश इवेंट हैंडलर बबलिंग चरण के दौरान पंजीकृत होते हैं। आप कैप्चरिंग चरण के दौरान इवेंट को हैंडल करने के लिए useCapture = true के साथ addEventListener(type, listener, useCapture) का उपयोग कर सकते हैं।

// एक HTML संरचना में: <div><p><span>यहां क्लिक करें</span></p></div> // यदि आप <span> पर क्लिक करते हैं: // कैप्चरिंग: window -> document -> html -> body -> div -> p -> span // बबलिंग: span -> p -> div -> body -> html -> document -> window /* JS उदाहरण div.addEventListener('click', () => console.log('Div क्लिक किया गया'), true); // कैप्चरिंग p.addEventListener('click', () => console.log('P क्लिक किया गया'), false); // बबलिंग span.addEventListener('click', () => console.log('Span क्लिक किया गया'), false); // बबलिंग // आउटपुट होगा: Div क्लिक किया गया, Span क्लिक किया गया, P क्लिक किया गया */

`JSON.parse` को मैन्युअल रूप से लागू करें (बुनियादी)

JSON.parse का एक बहुत ही बुनियादी संस्करण लागू करने का प्रयास करें (सरल वस्तुओं, सरणियों, स्ट्रिंग्स, संख्याओं को हैंडल करता है)।

स्पष्टीकरण: यह अपनी संपूर्णता में एक बहुत ही जटिल कार्य है, लेकिन एक लाइव कोडिंग वातावरण के लिए, आपसे एक बहुत ही सरलीकृत उपसमूह को हैंडल करने के लिए कहा जा सकता है। आपको स्ट्रिंग को पार्स करना होगा, ऑब्जेक्ट {} और सरणियों [] की सीमाओं, कुंजी-मूल्य जोड़े ("key": value), और बुनियादी डेटा प्रकारों की पहचान करनी होगी। eval या new Function इसमें धोखा दे सकते हैं, लेकिन वे खतरनाक हैं। एक वास्तविक पार्सर एक लेक्सर/टोकेनाइज़र और एक पार्सर का उपयोग करेगा।

function basicJsonParse(jsonString) { // चेतावनी: eval के रूप में new Function का उपयोग करना असुरक्षित है। // यह केवल प्रदर्शन के लिए एक सरलीकृत और असुरक्षित उदाहरण है। // एक वास्तविक कार्यान्वयन के लिए एक उचित पार्सर की आवश्यकता होती है। try { return (new Function('return ' + jsonString))(); } catch (e) { throw new SyntaxError('अवैध JSON: ' + e.message); } } console.log(basicJsonParse('{"a": 1, "b": ["x", "y"]}')); // { a: 1, b: ['x', 'y'] }

गहरे नेस्टेड सरणी को समतल करें

एक गहरे नेस्टेड सरणी को समतल करने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: पिछले समतलन (एक स्तर) के विपरीत, इसे किसी भी स्तर के नेस्टिंग को हैंडल करने की आवश्यकता है। रिकर्सन एक प्राकृतिक विकल्प है। सरणी के माध्यम से पुनरावृति करें। यदि कोई तत्व एक सरणी है, तो उस पर flatten को रिकर्सिव रूप से कॉल करें और परिणाम को संयोजित करें। अन्यथा, तत्व जोड़ें।

function deepFlatten(arr) { let flattened = []; arr.forEach(item => { if (Array.isArray(item)) { flattened = flattened.concat(deepFlatten(item)); } else { flattened.push(item); } }); return flattened; // ES2019+ एक बहुत ही सरल तरीका प्रदान करता है: // return arr.flat(Infinity); } console.log(deepFlatten([1, [2, [3, 4], 5], 6])); // [1, 2, 3, 4, 5, 6]

ट्राई (प्रीफिक्स ट्री) लागू करें

insert, search और startsWith विधियों के साथ एक ट्राई डेटा संरचना को लागू करें।

स्पष्टीकरण: एक ट्राई एक पेड़ जैसी डेटा संरचना है जिसका उपयोग स्ट्रिंग्स के डेटासेट में कुंजियों को कुशलता से संग्रहीत और पुनर्प्राप्त करने के लिए किया जाता है। प्रत्येक नोड एक वर्ण का प्रतिनिधित्व करता है, और रूट से पथ शब्द या प्रीफिक्स का प्रतिनिधित्व करते हैं।

class TrieNode { constructor() { this.children = {}; this.isEndOfWord = false; } } class Trie { constructor() { this.root = new TrieNode(); } insert(word) { let node = this.root; for (const char of word) { if (!node.children[char]) { node.children[char] = new TrieNode(); } node = node.children[char]; } node.isEndOfWord = true; } search(word) { let node = this.root; for (const char of word) { if (!node.children[char]) return false; node = node.children[char]; } return node.isEndOfWord; } startsWith(prefix) { let node = this.root; for (const char of prefix) { if (!node.children[char]) return false; node = node.children[char]; } return true; } } const trie = new Trie(); trie.insert('सेब'); console.log(trie.search('सेब')); // true console.log(trie.search('सेब')); // false console.log(trie.startsWith('सेब')); // true

सरणी को फेरबदल करें (फिशर-येट्स)

फिशर-येट्स (या कन्नुथ) एल्गोरिथम का उपयोग करके एक सरणी को उसके स्थान पर फेरबदल करने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: फिशर-येट्स एल्गोरिथम अंतिम तत्व से पहले तत्व तक एक सरणी को पुनरावृति करता है। प्रत्येक पुनरावृति में, यह वर्तमान तत्व को सरणी की शुरुआत से वर्तमान तत्व तक (समावेशी) यादृच्छिक रूप से चुने गए तत्व के साथ स्वैप करता है।

function shuffleArray(arr) { for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; // तत्वों को स्वैप करें } return arr; } console.log(shuffleArray([1, 2, 3, 4, 5])); // उदा., [3, 5, 1, 2, 4]

कार्यों को संयोजित करें

एक compose फ़ंक्शन को लागू करें जो कई फ़ंक्शन लेता है और एक नया फ़ंक्शन लौटाता है जो उन्हें दाएं से बाएं लागू करता है।

स्पष्टीकरण: फ़ंक्शन संरचना (f ∘ g)(x) = f(g(x)) एक फ़ंक्शन को दूसरे के परिणाम पर लागू करती है। एक सामान्य compose(f, g, h) फ़ंक्शन का अर्थ f(g(h(x))) होगा। एक सुरुचिपूर्ण कार्यान्वयन के लिए reduceRight का उपयोग करें।

function compose(...funcs) { return function(initialArg) { return funcs.reduceRight((acc, func) => func(acc), initialArg); }; } const add5 = x => x + 5; const multiply3 = x => x * 3; const subtract2 = x => x - 2; const composedFunc = compose(subtract2, multiply3, add5); console.log(composedFunc(10)); // (10 + 5) * 3 - 2 = 15 * 3 - 2 = 45 - 2 = 43

फ़ंक्शंस को पाइप करें

एक pipe फ़ंक्शन को लागू करें जो कई फ़ंक्शन लेता है और एक नया फ़ंक्शन लौटाता है जो उन्हें बाएं से दाएं लागू करता है।

स्पष्टीकरण: compose के समान, लेकिन आवेदन का क्रम उलटा है: pipe(f, g, h) का अर्थ h(g(f(x))) है। कार्यान्वयन के लिए reduce का उपयोग करें।

function pipe(...funcs) { return function(initialArg) { return funcs.reduce((acc, func) => func(acc), initialArg); }; } const add5 = x => x + 5; const multiply3 = x => x * 3; const subtract2 = x => x - 2; const pipedFunc = pipe(add5, multiply3, subtract2); console.log(pipedFunc(10)); // (10 + 5) * 3 - 2 = 15 * 3 - 2 = 45 - 2 = 43

सिक्का परिवर्तन समस्या

सिक्का संप्रदायों और एक राशि का एक सरणी को देखते हुए, उस राशि तक पहुंचने के लिए सिक्कों की न्यूनतम संख्या ज्ञात करें। प्रत्येक सिक्के की एक अनंत आपूर्ति मान लें।

स्पष्टीकरण: यह एक क्लासिक डायनेमिक प्रोग्रामिंग समस्या है। एक dp सरणी बनाएँ जहां dp[i] राशि i के लिए आवश्यक सिक्कों की न्यूनतम संख्या संग्रहीत करता है। dp[i] = min(dp[i - सिक्का]) + 1 सभी सिक्कों के लिए।

function coinChange(coins, amount) { const dp = new Array(amount + 1).fill(Infinity); dp[0] = 0; for (let i = 1; i <= amount; i++) { for (const coin of coins) { if (i - coin >= 0) { dp[i] = Math.min(dp[i], dp[i - coin] + 1); } } } return dp[amount] === Infinity ? -1 : dp[amount]; } console.log(coinChange([1, 2, 5], 11)); // 3 (5 + 5 + 1) console.log(coinChange([2], 3)); // -1

सबसे कम सामान्य पूर्वज (BST)

एक बाइनरी सर्च ट्री (BST) को देखते हुए, BST में दिए गए दो नोड्स के सबसे कम सामान्य पूर्वज (LCA) को ढूंढें।

स्पष्टीकरण: LCA सबसे गहरा नोड है जिसमें दिए गए दोनों नोड्स वंशज के रूप में होते हैं। एक BST में, आप रूट से ट्रैवर्स करके इसे ढूंढ सकते हैं। यदि दोनों नोड्स वर्तमान नोड से छोटे हैं, तो बाईं ओर जाएँ। यदि दोनों बड़े हैं, तो दाईं ओर जाएँ। यदि एक छोटा है और दूसरा बड़ा है (या एक वर्तमान नोड है), तो वर्तमान नोड LCA है।

class Node { constructor(val) { this.val = val; this.left = this.right = null; } } function lowestCommonAncestor(root, p, q) { let current = root; while (current) { if (p.val > current.val && q.val > current.val) { current = current.right; } else if (p.val < current.val && q.val < current.val) { current = current.left; } else { return current; // LCA मिल गया } } return null; // p और q के साथ एक वैध BST में ऐसा नहीं होना चाहिए } // उदाहरण: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 => LCA 6 है

बाइनरी ट्री को क्रमबद्ध और अक्रमबद्ध करें

एक बाइनरी ट्री को क्रमबद्ध और अक्रमबद्ध करने के लिए एक एल्गोरिथम डिज़ाइन करें।

स्पष्टीकरण: क्रमबद्धता एक पेड़ को एक स्ट्रिंग या सरणी में परिवर्तित करती है। अक्रमबद्धता पेड़ का पुनर्निर्माण करती है। एक सामान्य तरीका प्री-ऑर्डर ट्रैवर्सल (DFS) है। संरचना को संरक्षित करने के लिए नल नोड्स के लिए एक विशेष मार्कर (जैसे, '#') का उपयोग करें।

class Node { constructor(val) { this.val = val; this.left = this.right = null; } } function serialize(root) { const values = []; function dfs(node) { if (!node) { values.push('#'); return; } values.push(node.val); dfs(node.left); dfs(node.right); } dfs(root); return values.join(','); } function deserialize(data) { const values = data.split(','); let index = 0; function buildTree() { if (values[index] === '#') { index++; return null; } const node = new Node(parseInt(values[index])); index++; node.left = buildTree(); node.right = buildTree(); return node; } return buildTree(); } // उदाहरण: 1 -> [2, 3] -> [null, null, 4, 5] // क्रमबद्ध: '1,2,#,#,3,4,#,#,5,#,#'

`setTimeout` का उपयोग करके `setInterval` लागू करें

एक mySetInterval फ़ंक्शन को लागू करें जो setInterval की नकल करता है लेकिन पुनरावर्ती रूप से setTimeout का उपयोग करता है।

स्पष्टीकरण: setInterval एक फ़ंक्शन को हर N मिलीसेकंड में बार-बार निष्पादित करता है। आप प्रत्येक निष्पादन के बाद setTimeout के साथ एक फ़ंक्शन को खुद को कॉल करके इसे प्राप्त कर सकते हैं। आपको इसे साफ़ करने का एक तरीका भी चाहिए (myClearInterval)।

function mySetInterval(callback, delay, ...args) { const interval = { timerId: null }; function run() { interval.timerId = setTimeout(() => { callback.apply(this, args); run(); // अगली कॉल को शेड्यूल करें }, delay); } run(); return interval; // सफाई की अनुमति देने के लिए एक वस्तु लौटाएँ } function myClearInterval(interval) { clearTimeout(interval.timerId); } // उपयोग का उदाहरण: let count = 0; const intervalId = mySetInterval(() => { console.log(`नमस्ते: ${++count}`); if (count === 3) myClearInterval(intervalId); }, 500);

ग्राफ ट्रैवर्सल (BFS और DFS)

दिए गए ग्राफ (आसन्न सूची प्रतिनिधित्व) के लिए चौड़ाई-पहली खोज (BFS) और गहराई-पहली खोज (DFS) को लागू करें।

स्पष्टीकरण: BFS पहले पड़ोसियों की पड़ताल करता है (एक कतार का उपयोग करके), जबकि DFS प्रत्येक शाखा के साथ यथासंभव दूर की पड़ताल करता है (एक स्टैक या रिकर्सन का उपयोग करके)। चक्रों और अनावश्यक कार्य से बचने के लिए दौरा किए गए नोड्स का ट्रैक रखें।

const graph = { A: ['B', 'C'], B: ['D'], C: ['E'], D: [], E: ['F'], F: [] }; function bfs(graph, startNode) { const queue = [startNode]; const visited = new Set(); const result = []; visited.add(startNode); while (queue.length > 0) { const node = queue.shift(); result.push(node); for (const neighbor of graph[node]) { if (!visited.has(neighbor)) { visited.add(neighbor); queue.push(neighbor); } } } return result; } function dfs(graph, startNode) { const stack = [startNode]; const visited = new Set(); const result = []; while (stack.length > 0) { const node = stack.pop(); if (!visited.has(node)) { visited.add(node); result.push(node); // बाद में क्रम में संसाधित करने के लिए पड़ोसियों को उल्टे क्रम में जोड़ें (वैकल्पिक) for (let i = graph[node].length - 1; i >= 0; i--) { stack.push(graph[node][i]); } } } return result; } console.log('BFS:', bfs(graph, 'A')); // ['A', 'B', 'C', 'D', 'E', 'F'] console.log('DFS:', dfs(graph, 'A')); // ['A', 'B', 'D', 'C', 'E', 'F']

छवि घुमाएँ (मैट्रिक्स)

आपको एक n x n 2D मैट्रिक्स दिया गया है जो एक छवि का प्रतिनिधित्व करता है। छवि को उसके स्थान पर 90 डिग्री (घड़ी की दिशा में) घुमाएँ।

स्पष्टीकरण: इसे प्राप्त करने का एक सामान्य तरीका पहले मैट्रिक्स को ट्रांसपोज़ करना है (matrix[i][j] को matrix[j][i] के साथ स्वैप करके) और फिर प्रत्येक पंक्ति को उलटना है।

function rotate(matrix) { const n = matrix.length; // ट्रांसपोज़ करें for (let i = 0; i < n; i++) { for (let j = i; j < n; j++) { [matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]]; } } // प्रत्येक पंक्ति को उलटा करें for (let i = 0; i < n; i++) { matrix[i].reverse(); } return matrix; } const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; console.log(rotate(matrix)); // [[7, 4, 1], [8, 5, 2], [9, 6, 3]]

सर्पिल मैट्रिक्स ट्रैवर्सल

एक m x n मैट्रिक्स को देखते हुए, मैट्रिक्स के सभी तत्वों को सर्पिल क्रम में लौटाएँ।

स्पष्टीकरण: सीमाओं को परिभाषित करने के लिए चार पॉइंटर्स का उपयोग करें: top, bottom, left, right। शीर्ष पंक्ति, फिर दाहिनी कॉलम, फिर निचली पंक्ति, फिर बाईं कॉलम को पार करें, प्रत्येक ट्रैवर्सल के बाद सीमाओं को कम करें, जब तक कि left right को पार न कर जाए या top bottom को पार न कर जाए।

function spiralOrder(matrix) { if (!matrix || matrix.length === 0) return []; const rows = matrix.length, cols = matrix[0].length; const result = []; let top = 0, bottom = rows - 1, left = 0, right = cols - 1; while (top <= bottom && left <= right) { for (let i = left; i <= right; i++) result.push(matrix[top][i]); top++; for (let i = top; i <= bottom; i++) result.push(matrix[i][right]); right--; if (top <= bottom) { for (let i = right; i >= left; i--) result.push(matrix[bottom][i]); bottom--; } if (left <= right) { for (let i = bottom; i >= top; i--) result.push(matrix[i][left]); left++; } } return result; } const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; console.log(spiralOrder(matrix)); // [1, 2, 3, 6, 9, 8, 7, 4, 5]

मैट्रिक्स में शून्य सेट करें

एक m x n मैट्रिक्स को देखते हुए, यदि कोई तत्व 0 है, तो उसकी पूरी पंक्ति और कॉलम को 0 पर सेट करें। इसे यथास्थान करें।

स्पष्टीकरण: एक अनुभवहीन दृष्टिकोण के लिए O(m*n) अतिरिक्त स्थान की आवश्यकता होती है। इसे O(1) (या O(m+n)) स्थान में करने के लिए, आप पहली पंक्ति और पहली कॉलम का उपयोग इस बारे में जानकारी संग्रहीत करने के लिए कर सकते हैं कि कौन सी पंक्तियों/कॉलम को शून्य किया जाना चाहिए। आपको यह जानने के लिए अलग-अलग संकेतकों की आवश्यकता है कि क्या पहली पंक्ति/कॉलम को स्वयं शून्य किया जाना चाहिए।

function setZeroes(matrix) { const rows = matrix.length, cols = matrix[0].length; let firstColZero = false; for (let r = 0; r < rows; r++) { if (matrix[r][0] === 0) firstColZero = true; for (let c = 1; c < cols; c++) { if (matrix[r][c] === 0) { matrix[r][0] = 0; matrix[0][c] = 0; } } } for (let r = rows - 1; r >= 0; r--) { for (let c = cols - 1; c >= 1; c--) { if (matrix[r][0] === 0 || matrix[0][c] === 0) { matrix[r][c] = 0; } } if (firstColZero) matrix[r][0] = 0; } return matrix; } // उदाहरण: [[1,1,1],[1,0,1],[1,1,1]] => [[1,0,1],[0,0,0],[1,0,1]]

`Promise.race` को लागू करें

एक फ़ंक्शन को लागू करें जो Promise.race के रूप में व्यवहार करता है।

स्पष्टीकरण: Promise.race वादों का एक सरणी लेता है और एक एकल वादा लौटाता है। यह वादा तब हल होता है (पूरा या अस्वीकृत) जैसे ही इनपुट वादों में से कोई भी हल हो जाता है, उस वादे के मूल्य या कारण के साथ।

function myPromiseRace(promises) { return new Promise((resolve, reject) => { if (!promises || promises.length === 0) { return; // या विनिर्देश के आधार पर हल/अस्वीकृत करें } promises.forEach(promise => { Promise.resolve(promise).then(resolve, reject); }); }); } const p1 = new Promise((resolve) => setTimeout(resolve, 500, 'एक')); const p2 = new Promise((resolve) => setTimeout(resolve, 100, 'दो')); myPromiseRace([p1, p2]).then(value => console.log(value)); // 'दो'

सिंगलटन पैटर्न

जावास्क्रिप्ट में सिंगलटन डिज़ाइन पैटर्न को लागू करें।

स्पष्टीकरण: सिंगलटन पैटर्न सुनिश्चित करता है कि एक वर्ग में केवल एक ही इंस्टेंस है और इसे वैश्विक पहुंच बिंदु प्रदान करता है। इसे इंस्टेंस को बनाए रखने के लिए एक क्लोजर का उपयोग करके प्राप्त किया जा सकता है।

const Singleton = (function() { let instance; function createInstance() { // निजी विधियाँ और चर const privateVar = 'मैं निजी हूँ'; function privateMethod() { console.log('निजी'); } return { // सार्वजनिक विधियाँ और चर publicVar: 'मैं सार्वजनिक हूँ', publicMethod: function() { console.log('सार्वजनिक'); }, getPrivate: function() { return privateVar; } }; } return { getInstance: function() { if (!instance) { instance = createInstance(); } return instance; } }; })(); const instance1 = Singleton.getInstance(); const instance2 = Singleton.getInstance(); console.log(instance1 === instance2); // true console.log(instance1.getPrivate()); // 'मैं निजी हूँ'

आईपी पता मान्य करें

यह जाँचने के लिए एक फ़ंक्शन लिखें कि क्या दी गई स्ट्रिंग एक वैध IPv4 या IPv6 पता है।

स्पष्टीकरण: IPv4 के लिए, जाँच करें कि क्या डॉट्स द्वारा अलग किए गए 4 नंबर (0-255) हैं, बिना अग्रणी शून्य के (केवल '0' को छोड़कर)। IPv6 के लिए, जाँच करें कि क्या कॉलन द्वारा अलग किए गए 1-4 हेक्साडेसिमल अंकों के 8 समूह हैं (जैसे '::' जैसे विविधताओं को संभालें)। रेगक्स का उपयोग किया जा सकता है, लेकिन साक्षात्कार के लिए मैन्युअल पार्सिंग अक्सर अधिक स्पष्ट होती है।

function validIPAddress(IP) { function isIPv4(s) { const parts = s.split('.'); if (parts.length !== 4) return false; for (const part of parts) { if (!/^[0-9]+$/.test(part)) return false; if (part.length > 1 && part.startsWith('0')) return false; const num = parseInt(part); if (num < 0 || num > 255) return false; } return true; } function isIPv6(s) { const parts = s.split(':'); if (parts.length !== 8) return false; // सरलीकृत: '::' नहीं for (const part of parts) { if (part.length < 1 || part.length > 4) return false; if (!/^[0-9a-fA-F]+$/.test(part)) return false; } return true; } if (IP.includes('.')) return isIPv4(IP) ? 'IPv4' : 'Neither'; if (IP.includes(':')) return isIPv6(IP) ? 'IPv6' : 'Neither'; return 'Neither'; } console.log(validIPAddress('172.16.254.1')); // IPv4 console.log(validIPAddress('2001:0db8:85a3:0000:0000:8a2e:0370:7334')); // IPv6 (सरलीकृत) console.log(validIPAddress('256.256.256.256')); // Neither

पीक एलिमेंट खोजें

एक पीक एलिमेंट एक ऐसा एलिमेंट होता है जो अपने पड़ोसियों से सख्ती से बड़ा होता है। इनपुट सरणी nums को देखते हुए, एक पीक एलिमेंट ढूंढें और उसका इंडेक्स लौटाएँ।

स्पष्टीकरण: चूंकि कोई भी पीक काम करेगा, और nums[-1] और nums[n] को -Infinity माना जाता है, आप एक संशोधित बाइनरी खोज का उपयोग कर सकते हैं। यदि nums[mid] nums[mid+1] से कम है, तो दाईं ओर एक पीक मौजूद होना चाहिए। अन्यथा, बाईं ओर एक पीक मौजूद होना चाहिए (या mid स्वयं एक पीक है)।

function findPeakElement(nums) { let left = 0; let right = nums.length - 1; while (left < right) { let mid = Math.floor((left + right) / 2); if (nums[mid] < nums[mid + 1]) { left = mid + 1; // पीक दाईं ओर है } else { right = mid; // पीक mid है या बाईं ओर है } } return left; // 'left' एक पीक का इंडेक्स होगा } console.log(findPeakElement([1, 2, 3, 1])); // 2 (3 का इंडेक्स) console.log(findPeakElement([1, 2, 1, 3, 5, 6, 4])); // 5 (6 का इंडेक्स) या 1 (2 का इंडेक्स)

बिट्स गिनें

एक पूर्णांक n को देखते हुए, लंबाई n + 1 का एक सरणी ans लौटाएँ ताकि प्रत्येक i (0 <= i <= n) के लिए, ans[i] i के बाइनरी प्रतिनिधित्व में 1s की संख्या है।

स्पष्टीकरण: आप इसे डायनेमिक प्रोग्रामिंग का उपयोग करके हल कर सकते हैं। संबंध देखें: dp[i] = dp[i >> 1] + (i & 1)i में 1s की संख्या i में 1s की संख्या है जिसे दाईं ओर स्थानांतरित किया गया है (यानी, i/2), प्लस 1 यदि i विषम है।

function countBits(n) { const dp = new Array(n + 1).fill(0); for (let i = 1; i <= n; i++) { dp[i] = dp[i >> 1] + (i & 1); // या: dp[i] = dp[i & (i - 1)] + 1; (अंतिम सेट बिट हटाता है) } return dp; } console.log(countBits(5)); // [0, 1, 1, 2, 1, 2]

दो की शक्ति

एक पूर्णांक n को देखते हुए, true लौटाएँ यदि यह दो की शक्ति है। अन्यथा, false लौटाएँ।

स्पष्टीकरण: बाइनरी प्रतिनिधित्व में दो की शक्ति में ठीक एक '1' बिट होता है (उदाहरण के लिए, 1=1, 2=10, 4=100, 8=1000)। बिट्स के साथ एक चतुर चाल यह जाँचने के लिए है कि n > 0 और (n & (n - 1)) === 0। यदि n दो की शक्ति है, तो n-1 में उस '1' के नीचे सभी बिट्स '1' पर सेट होंगे। उन पर AND लगाने से, परिणाम 0 होता है।

function isPowerOfTwo(n) { return n > 0 && (n & (n - 1)) === 0; } console.log(isPowerOfTwo(16)); // true console.log(isPowerOfTwo(1)); // true console.log(isPowerOfTwo(18)); // false

अंतराल मर्ज करें

intervals नामक एक सरणी दी गई है जहाँ intervals[i] = [starti, endi], सभी ओवरलैपिंग अंतरालों को मर्ज करें और गैर-ओवरलैपिंग अंतरालों की एक सरणी लौटाएं।

स्पष्टीकरण: सबसे पहले, अंतरालों को उनके शुरुआती समय के अनुसार क्रमबद्ध करें। फिर, क्रमबद्ध अंतरालों के माध्यम से पुनरावृति करें। यदि वर्तमान अंतराल परिणाम सूची में अंतिम अंतराल के साथ ओवरलैप होता है, तो अंतिम अंतराल के अंतिम समय को अपडेट करके उन्हें मर्ज करें। अन्यथा, वर्तमान अंतराल को परिणाम सूची में जोड़ें।

function mergeIntervals(intervals) { if (intervals.length === 0) return []; intervals.sort((a, b) => a[0] - b[0]); const merged = [intervals[0]]; for (let i = 1; i < intervals.length; i++) { const last = merged[merged.length - 1]; const current = intervals[i]; if (current[0] <= last[1]) { // ओवरलैप: मर्ज करें last[1] = Math.max(last[1], current[1]); } else { // कोई ओवरलैप नहीं: नया अंतराल जोड़ें merged.push(current); } } return merged; } console.log(mergeIntervals([[1, 3], [2, 6], [8, 10], [15, 18]])); // [[1, 6], [8, 10], [15, 18]]

शब्द तोड़ना

s नामक एक स्ट्रिंग और स्ट्रिंग wordDict का एक शब्दकोश दिया गया है, यदि s को शब्दकोश से एक या अधिक शब्दों के स्पेस-सेपरेटेड अनुक्रम में खंडित किया जा सकता है तो true लौटाएं।

स्पष्टीकरण: डायनेमिक प्रोग्रामिंग का उपयोग करें। एक बूलियन सरणी dp बनाएं जहां dp[i] सत्य है यदि सबस्ट्रिंग s[0...i-1] को खंडित किया जा सकता है। dp[i] सत्य है यदि कोई j < i मौजूद है जैसे कि dp[j] सत्य है और सबस्ट्रिंग s[j...i-1] शब्दकोश में है।

function wordBreak(s, wordDict) { const wordSet = new Set(wordDict); const n = s.length; const dp = new Array(n + 1).fill(false); dp[0] = true; // मूल मामला: खाली स्ट्रिंग for (let i = 1; i <= n; i++) { for (let j = 0; j < i; j++) { if (dp[j] && wordSet.has(s.substring(j, i))) { dp[i] = true; break; } } } return dp[n]; } console.log(wordBreak('leetcode', ['leet', 'code'])); // true console.log(wordBreak('applepenapple', ['apple', 'pen'])); // true console.log(wordBreak('catsandog', ['cats', 'dog', 'sand', 'and', 'cat'])); // false

`Array.prototype.flat` लागू करें

Array.prototype.flat का अपना संस्करण लागू करें, जो एक निर्दिष्ट गहराई तक सभी उप-सरणियों के तत्वों को पुनरावर्ती रूप से संयोजित करके एक नई सरणी बनाता है।

स्पष्टीकरण: पुनरावर्तन का उपयोग करें। सरणी के माध्यम से पुनरावृति करें। यदि कोई तत्व एक सरणी है और वर्तमान गहराई निर्दिष्ट गहराई से कम है, तो उस पर flatten को पुनरावर्ती रूप से कॉल करें। अन्यथा, तत्व जोड़ें। डिफ़ॉल्ट गहराई 1 को संभालें।

function myFlat(arr, depth = 1) { let flattened = []; arr.forEach(item => { if (Array.isArray(item) && depth > 0) { flattened.push(...myFlat(item, depth - 1)); } else { flattened.push(item); } }); return flattened; } console.log(myFlat([1, [2, [3, 4], 5], 6])); // [2, [3, 4], 5] console.log(myFlat([1, [2, [3, 4], 5], 6], 2)); // [1, 2, 3, 4, 5, 6]

एक स्ट्रिंग में शब्दों को उलट दें

s नामक एक इनपुट स्ट्रिंग दी गई है, शब्दों के क्रम को उलट दें।

स्पष्टीकरण: एक 'शब्द' को गैर-स्पेस वर्णों के अनुक्रम के रूप में परिभाषित किया गया है। स्ट्रिंग को ट्रिम करें, इसे एक या अधिक स्पेस द्वारा विभाजित करें, कई स्पेसेस से उत्पन्न होने वाली किसी भी खाली स्ट्रिंग को फ़िल्टर करें, सरणी को उलट दें और इसे सिंगल स्पेसेस के साथ फिर से जोड़ दें।

function reverseWords(s) { return s.trim().split(/\s+/).reverse().join(' '); } console.log(reverseWords('el cielo es azul')); // 'azul es cielo el' console.log(reverseWords(' hola mundo ')); // 'mundo hola' console.log(reverseWords('un buen ejemplo')); // 'ejemplo buen un'

क्वेरी स्ट्रिंग पार्सर

एक URL क्वेरी स्ट्रिंग को एक ऑब्जेक्ट में पार्स करने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: स्ट्रिंग को & द्वारा विभाजित करें। प्रत्येक भाग के लिए, कुंजी और मान प्राप्त करने के लिए = द्वारा विभाजित करें। कुंजी और मान दोनों के लिए URI घटकों को डिकोड करें। उन मामलों को संभालें जहां एक कुंजी कई बार दिखाई दे सकती है (एक सरणी बनाएं) या उसका कोई मान नहीं है।

function parseQueryString(query) { if (query.startsWith('?')) { query = query.substring(1); } const result = {}; if (!query) return result; query.split('&').forEach(pair => { const [key, value] = pair.split('='); const decodedKey = decodeURIComponent(key); const decodedValue = value !== undefined ? decodeURIComponent(value) : true; if (result.hasOwnProperty(decodedKey)) { if (Array.isArray(result[decodedKey])) { result[decodedKey].push(decodedValue); } else { result[decodedKey] = [result[decodedKey], decodedValue]; } } else { result[decodedKey] = decodedValue; } }); return result; } console.log(parseQueryString('?foo=bar&baz=qux&baz=quux&corge')); // { foo: 'bar', baz: ['qux', 'quux'], corge: true }

मान्यकरण के लिए `Proxy` का उपयोग करें

ऑब्जेक्ट प्रॉपर्टी मान्यकरण के लिए Proxy ऑब्जेक्ट का उपयोग कैसे करें, इसका प्रदर्शन करें।

स्पष्टीकरण: एक Proxy आपको किसी ऑब्जेक्ट पर की गई कार्रवाइयों को इंटरसेप्ट और अनुकूलित करने की अनुमति देता है। मानों को प्रॉपर्टी में असाइन करने से पहले मान्य करने के लिए set ट्रैप का उपयोग करें। यदि मान्यकरण विफल रहता है तो एक त्रुटि फेंक दें।

const validator = { set: function(obj, prop, value) { if (prop === 'age') { if (!Number.isInteger(value)) { throw new TypeError('उम्र एक पूर्णांक नहीं है'); } if (value < 0 || value > 150) { throw new RangeError('उम्र अमान्य लगती है'); } } // डिफ़ॉल्ट व्यवहार: प्रॉपर्टी सेट करें obj[prop] = value; return true; } }; const person = {}; const personProxy = new Proxy(person, validator); personProxy.age = 30; // ठीक है console.log(personProxy.age); // 30 // personProxy.age = 'treinta'; // TypeError फेंकता है // personProxy.age = 200; // RangeError फेंकता है

मीटिंग के कमरे

मीटिंग समय अंतरालों की एक सरणी [[start1, end1], [start2, end2], ...] दी गई है, निर्धारित करें कि क्या कोई व्यक्ति सभी मीटिंगों में भाग ले सकता है।

स्पष्टीकरण: यदि कोई व्यक्ति सभी मीटिंगों में भाग ले सकता है, तो इसका मतलब है कि कोई भी दो मीटिंग ओवरलैप नहीं होती हैं। इसकी जांच करने के लिए, अंतरालों को उनके शुरुआती समय से क्रमबद्ध करें। फिर, क्रमबद्ध अंतरालों के माध्यम से पुनरावृति करें और जांचें कि क्या वर्तमान मीटिंग का शुरुआती समय पिछली मीटिंग के अंतिम समय से पहले है। यदि ऐसा है, तो एक ओवरलैप है और व्यक्ति सभी में भाग नहीं ले सकता है।

function canAttendMeetings(intervals) { if (intervals.length < 2) return true; intervals.sort((a, b) => a[0] - b[0]); for (let i = 1; i < intervals.length; i++) { if (intervals[i][0] < intervals[i - 1][1]) { return false; // ओवरलैप का पता चला } } return true; } console.log(canAttendMeetings([[0, 30], [5, 10], [15, 20]])); // false (5<30) console.log(canAttendMeetings([[7, 10], [2, 4]])); // true

`Promise.any` लागू करें

Promise.any की तरह व्यवहार करने वाला एक फ़ंक्शन लागू करें।

स्पष्टीकरण: Promise.any प्रॉमिसेस की एक सरणी लेता है और एक एकल वादा लौटाता है। यह वादा जैसे ही किसी भी इनपुट प्रॉमिसेस को पूरा किया जाता है, वैसे ही पूरा हो जाता है। यदि सभी इनपुट प्रॉमिसेस को अस्वीकार कर दिया जाता है, तो यह सभी अस्वीकृति कारणों वाले AggregateError के साथ अस्वीकार कर दिया जाता है।

function myPromiseAny(promises) { return new Promise((resolve, reject) => { const numPromises = promises.length; if (numPromises === 0) { reject(new AggregateError([], 'सभी प्रॉमिसेस अस्वीकार कर दिए गए थे')); return; } let rejectionCount = 0; const errors = []; promises.forEach((promise, index) => { Promise.resolve(promise) .then(resolve) // जैसे ही एक पूरा हो जाए, हल करें .catch(error => { errors[index] = error; rejectionCount++; if (rejectionCount === numPromises) { reject(new AggregateError(errors, 'सभी प्रॉमिसेस अस्वीकार कर दिए गए थे')); } }); }); }); } // उदाहरण: myPromiseAny([Promise.reject('err1'), Promise.resolve('ok')]) -> 'ok' // उदाहरण: myPromiseAny([Promise.reject('err1'), Promise.reject('err2')]) -> AggregateError

पर्यवेक्षक पैटर्न

जावास्क्रिप्ट में पर्यवेक्षक (प्रकाशक/सदस्य) डिज़ाइन पैटर्न को लागू करें।

स्पष्टीकरण: पर्यवेक्षक पैटर्न ऑब्जेक्ट्स के बीच एक-से-कई निर्भरता को परिभाषित करता है। जब एक ऑब्जेक्ट (विषय) स्थिति बदलता है, तो उसके सभी निर्भर (पर्यवेक्षक) स्वचालित रूप से सूचित और अपडेट होते हैं। विषय पर्यवेक्षकों की एक सूची रखता है और उन्हें जोड़ने, हटाने और सूचित करने के लिए तरीके प्रदान करता है।

class Subject { constructor() { this.observers = []; } subscribe(observer) { this.observers.push(observer); } unsubscribe(observer) { this.observers = this.observers.filter(obs => obs !== observer); } notify(data) { this.observers.forEach(observer => observer.update(data)); } } class Observer { constructor(name) { this.name = name; } update(data) { console.log(`${this.name} प्राप्त: ${data}`); } } const subject = new Subject(); const obs1 = new Observer('पर्यवेक्षक 1'); const obs2 = new Observer('पर्यवेक्षक 2'); subject.subscribe(obs1); subject.subscribe(obs2); subject.notify('कुछ हुआ है!'); // पर्यवेक्षक 1 प्राप्त: कुछ हुआ है! // पर्यवेक्षक 2 प्राप्त: कुछ हुआ है!

डुप्लीकेट नंबर ढूंढें

पूर्णांकों की एक सरणी nums दी गई है जिसमें n + 1 पूर्णांक हैं जहां प्रत्येक पूर्णांक [1, n] समावेशी सीमा में है, दोहराया गया नंबर ढूंढें।

स्पष्टीकरण: चूंकि संख्याएँ [1, n] में हैं और सरणी का आकार n+1 है, इसलिए कम से कम एक डुप्लीकेट की गारंटी है। इसे 'लिंक्ड लिस्ट में चक्र ढूंढें' (फ्लॉइड की टॉर्टोइस और हेयर) समस्या के लिए मैप किया जा सकता है। सरणी मानों को पॉइंटर के रूप में व्यवहार करें: इंडेक्स -> nums[इंडेक्स]

function findDuplicate(nums) { let tortoise = nums[0]; let hare = nums[0]; // चरण 1: चौराहे का बिंदु ढूंढें do { tortoise = nums[tortoise]; hare = nums[nums[hare]]; } while (tortoise !== hare); // चरण 2: चक्र में प्रवेश बिंदु ढूंढें let ptr1 = nums[0]; let ptr2 = tortoise; while (ptr1 !== ptr2) { ptr1 = nums[ptr1]; ptr2 = nums[ptr2]; } return ptr1; } console.log(findDuplicate([1, 3, 4, 2, 2])); // 2 console.log(findDuplicate([3, 1, 3, 4, 2])); // 3

बुनियादी HTML सैनिटाइज़र

एक HTML स्ट्रिंग को साफ करने के लिए एक बुनियादी फ़ंक्शन लिखें, संभावित रूप से हानिकारक टैग्स (जैसे <script>) को हटाते हुए सुरक्षित टैग्स (जैसे <p>, <b>) को बनाए रखते हुए।

स्पष्टीकरण: यह एक जटिल विषय है, और वास्तविक दुनिया के सैनिटाइज़र परिष्कृत होते हैं। एक साक्षात्कार के लिए, एक बुनियादी दृष्टिकोण में विशिष्ट टैग्स को हटाने के लिए रेगुलर एक्सप्रेशन का उपयोग करना या केवल टैग्स की एक व्हाइटलिस्ट की अनुमति देना शामिल हो सकता है। यह उत्पादन के लिए सुरक्षित नहीं है।

function basicSanitize(html) { // चेतावनी: यह एक बहुत ही बुनियादी और असुरक्षित उदाहरण है। // इसे उत्पादन में उपयोग न करें। DOMPurify जैसी लाइब्रेरी का उपयोग करें। // स्क्रिप्ट टैग हटाएँ let sanitized = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, ''); // उदाहरण: onclick एट्रीब्यूट हटाएँ (बहुत बुनियादी) sanitized = sanitized.replace(/\s(on\w+)=['"]?[^'"]*['"]?/gi, ''); return sanitized; } console.log(basicSanitize('<p>Hola <script>alert("XSS")</script> <b onclick="danger()">Mundo</b></p>')); // <p>Hola <b >Mundo</b></p>

एडिट दूरी

दो स्ट्रिंग word1 और word2 दी गई हैं, word1 को word2 में बदलने के लिए आवश्यक न्यूनतम संचालन (इंसर्ट, डिलीट या प्रतिस्थापन) की संख्या लौटाएं।

स्पष्टीकरण: यह एक क्लासिक डायनेमिक प्रोग्रामिंग समस्या है (लेवनश्टाइन दूरी)। एक 2D सरणी dp बनाएं जहां dp[i][j] word1 के पहले i वर्णों और word2 के पहले j वर्णों के बीच संपादन दूरी है। पुनरावर्ती संबंध में सम्मिलन, विलोपन और प्रतिस्थापन की लागत पर विचार करना शामिल है।

function minDistance(word1, word2) { const m = word1.length, n = word2.length; const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0)); for (let i = 0; i <= m; i++) dp[i][0] = i; for (let j = 0; j <= n; j++) dp[0][j] = j; for (let i = 1; i <= m; i++) { for (let j = 1; j <= n; j++) { const cost = word1[i - 1] === word2[j - 1] ? 0 : 1; dp[i][j] = Math.min( dp[i - 1][j] + 1, // विलोपन dp[i][j - 1] + 1, // सम्मिलन dp[i - 1][j - 1] + cost // प्रतिस्थापन/मिलान ); } } return dp[m][n]; } console.log(minDistance('caballo', 'rosa')); // 3 console.log(minDistance('intencion', 'ejecucion')); // 5

सबसे लंबी बढ़ती उप-अनुक्रम (LIS)

पूर्णांकों की एक सरणी nums दी गई है, सबसे लंबी सख्ती से बढ़ती उप-अनुक्रम की लंबाई लौटाएं।

स्पष्टीकरण: डायनेमिक प्रोग्रामिंग का उपयोग करें। dp[i] को इंडेक्स i पर समाप्त होने वाली LIS की लंबाई होने दें। dp[i] की गणना करने के लिए, सभी j < i ऐसे ढूंढें कि nums[j] < nums[i], और dp[i] = 1 + max(dp[j]) लें। अंतिम उत्तर dp सरणी में अधिकतम मान है।

function lengthOfLIS(nums) { if (nums.length === 0) return 0; const n = nums.length; const dp = new Array(n).fill(1); let maxLength = 1; for (let i = 1; i < n; i++) { for (let j = 0; j < i; j++) { if (nums[i] > nums[j]) { dp[i] = Math.max(dp[i], dp[j] + 1); } } maxLength = Math.max(maxLength, dp[i]); } return maxLength; } console.log(lengthOfLIS([10, 9, 2, 5, 3, 7, 101, 18])); // 4 (2, 3, 7, 101)

N-क्वीन समस्या

N-क्वीन समस्या N×N बोर्ड पर N शतरंज की क्वींस को इस तरह से रखने की समस्या है कि कोई भी क्वीन एक-दूसरे को धमकी न दे। N दिया गया है, एक मान्य समाधान (या सभी) लौटाएं।

स्पष्टीकरण: बैकट्रैकिंग का उपयोग करें। क्वींस को पंक्ति-दर-पंक्ति रखें। प्रत्येक पंक्ति के लिए, प्रत्येक कॉलम में एक क्वीन रखने का प्रयास करें। रखने से पहले, जांचें कि प्रस्तावित स्थिति सुरक्षित है (पिछली पंक्तियों में क्वींस द्वारा हमला नहीं किया गया है)। यदि सुरक्षित है, तो इसे रखें और अगली पंक्ति के लिए पुनरावृति करें। यदि पुनरावृति विफल हो जाती है, तो बैकट्रैक करें (क्वीन को हटा दें) और अगले कॉलम का प्रयास करें।

function solveNQueens(n) { const results = []; const board = Array(n).fill('.').map(() => Array(n).fill('.')); function isSafe(row, col) { for (let i = 0; i < row; i++) if (board[i][col] === 'Q') return false; // कॉलम की जांच करें for (let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) if (board[i][j] === 'Q') return false; // ऊपरी-बाएं विकर्ण की जांच करें for (let i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) if (board[i][j] === 'Q') return false; // ऊपरी-दाएं विकर्ण की जांच करें return true; } function backtrack(row) { if (row === n) { results.push(board.map(r => r.join(''))); return; } for (let col = 0; col < n; col++) { if (isSafe(row, col)) { board[row][col] = 'Q'; backtrack(row + 1); board[row][col] = '.'; // बैकट्रैक } } } backtrack(0); return results; } console.log(solveNQueens(4)); // [ [ '.Q..', '...Q', 'Q...', '..Q.' ], [ '..Q.', 'Q...', '...Q', '.Q..' ] ]

निजी डेटा के लिए `WeakMap` का उपयोग करें

क्लास इंस्टेंस के लिए निजी डेटा को संग्रहीत करने के लिए WeakMap का उपयोग कैसे करें, इसका प्रदर्शन करें।

स्पष्टीकरण: WeakMap आपको एक ऑब्जेक्ट के साथ डेटा को इस तरह से जोड़ने की अनुमति देता है जो गारबेज कलेक्शन को नहीं रोकता है यदि ऑब्जेक्ट को अब संदर्भित नहीं किया जाता है। यह जावास्क्रिप्ट कक्षाओं में 'निजी' सदस्यों को बनाने के लिए उपयोगी है इससे पहले कि देशी निजी फ़ील्ड व्यापक रूप से उपलब्ध हों या विशिष्ट उपयोग मामलों के लिए।

const privateData = new WeakMap(); class Person { constructor(name, age) { privateData.set(this, { name: name, age: age }); } getName() { return privateData.get(this).name; } getAge() { return privateData.get(this).age; } celebrateBirthday() { privateData.get(this).age++; } } const person = new Person('एलिसिया', 30); console.log(person.getName()); // एलिसिया person.celebrateBirthday(); console.log(person.getAge()); // 31 // console.log(person.name); // अपरिभाषित - 'name' एक सार्वजनिक प्रॉपर्टी नहीं है // console.log(privateData.get(person)); // सुलभ, लेकिन सीधे 'person.' के माध्यम से नहीं

`Promise.allSettled` लागू करें

Promise.allSettled की तरह व्यवहार करने वाला एक फ़ंक्शन लागू करें।

स्पष्टीकरण: Promise.allSettled प्रॉमिसेस की एक सरणी लेता है और एक एकल वादा लौटाता है। यह वादा तब पूरा होता है जब सभी इनपुट प्रॉमिसेस हल हो जाते हैं (या तो पूरे हो जाते हैं या अस्वीकार कर दिए जाते हैं)। पूर्ति मूल्य ऑब्जेक्ट्स की एक सरणी है, प्रत्येक एक वादे के परिणाम का वर्णन करता है ({status: 'fulfilled', value: ...} या {status: 'rejected', reason: ...})।

function myPromiseAllSettled(promises) { return new Promise((resolve) => { const numPromises = promises.length; const results = []; let settledCount = 0; if (numPromises === 0) { resolve([]); return; } promises.forEach((promise, index) => { Promise.resolve(promise) .then(value => { results[index] = { status: 'fulfilled', value: value }; }) .catch(reason => { results[index] = { status: 'rejected', reason: reason }; }) .finally(() => { settledCount++; if (settledCount === numPromises) { resolve(results); } }); }); }); } // उदाहरण: myPromiseAllSettled([Promise.resolve(1), Promise.reject('err')]) // -> [{status: 'fulfilled', value: 1}, {status: 'rejected', reason: 'err'}]

दो क्रमबद्ध सरणियों का मध्यिका ज्ञात करें

क्रमबद्ध सरणी nums1 और nums2 क्रमशः m और n आकार के दिए गए हैं, दो क्रमबद्ध सरणियों का मध्यिका लौटाएं।

स्पष्टीकरण: यह एक कठिन समस्या है जिसे अक्सर छोटी सरणी पर बाइनरी खोज दृष्टिकोण से हल किया जाता है। लक्ष्य दोनों सरणियों को इस तरह से विभाजित करना है कि बाईं ओर के सभी तत्व दाईं ओर के सभी तत्वों से छोटे या बराबर हों, और बाईं ओर के तत्वों की संख्या दाईं ओर के बराबर (या एक अधिक) हो। मध्यिका को सीमांत तत्वों से गणना की जा सकती है।

function findMedianSortedArrays(nums1, nums2) { if (nums1.length > nums2.length) [nums1, nums2] = [nums2, nums1]; // सुनिश्चित करें कि nums1 सबसे छोटा है const m = nums1.length, n = nums2.length; let low = 0, high = m; while (low <= high) { const partitionX = Math.floor((low + high) / 2); const partitionY = Math.floor((m + n + 1) / 2) - partitionX; const maxX = (partitionX === 0) ? -Infinity : nums1[partitionX - 1]; const minX = (partitionX === m) ? Infinity : nums1[partitionX]; const maxY = (partitionY === 0) ? -Infinity : nums2[partitionY - 1]; const minY = (partitionY === n) ? Infinity : nums2[partitionY]; if (maxX <= minY && maxY <= minX) { if ((m + n) % 2 === 0) { return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2; } else { return Math.max(maxX, maxY); } } else if (maxX > minY) { high = partitionX - 1; } else { low = partitionX + 1; } } throw new Error('इनपुट सरणियाँ क्रमबद्ध नहीं हैं'); } console.log(findMedianSortedArrays([1, 3], [2])); // 2.0 console.log(findMedianSortedArrays([1, 2], [3, 4])); // 2.5

सुडोकू हल करने वाला

खाली कोशिकाओं को भरकर एक सुडोकू पहेली को हल करने के लिए एक कार्यक्रम लिखें।

स्पष्टीकरण: बैकट्रैकिंग का उपयोग करें। एक खाली सेल ढूंढें। इसे 1 से 9 तक की संख्याओं से भरने का प्रयास करें। प्रत्येक संख्या के लिए, जांचें कि क्या यह मान्य है (सुडोकू नियमों का उल्लंघन नहीं करता है)। यदि मान्य है, तो हल करने वाले को पुनरावर्ती रूप से कॉल करें। यदि पुनरावृति सत्य लौटाती है, तो एक समाधान मिल गया है। यदि नहीं, तो बैकट्रैक करें (सेल को रीसेट करें) और अगली संख्या का प्रयास करें।

function solveSudoku(board) { function isValid(row, col, numStr) { for (let i = 0; i < 9; i++) { if (board[row][i] === numStr) return false; // पंक्ति की जांच करें if (board[i][col] === numStr) return false; // कॉलम की जांच करें const boxRow = 3 * Math.floor(row / 3) + Math.floor(i / 3); const boxCol = 3 * Math.floor(col / 3) + i % 3; if (board[boxRow][boxCol] === numStr) return false; // बॉक्स की जांच करें } return true; } function backtrack() { for (let r = 0; r < 9; r++) { for (let c = 0; c < 9; c++) { if (board[r][c] === '.') { for (let n = 1; n <= 9; n++) { const numStr = String(n); if (isValid(r, c, numStr)) { board[r][c] = numStr; if (backtrack()) return true; board[r][c] = '.'; // बैकट्रैक } } return false; // कोई वैध संख्या नहीं मिली } } } return true; // बोर्ड हल हो गया } backtrack(); return board; } // उदाहरण के लिए खाली कोशिकाओं के लिए '.' के साथ 9x9 बोर्ड की आवश्यकता है।

एक बुनियादी मिडलवेयर पैटर्न लागू करें

एक साधारण मिडलवेयर पैटर्न लागू करें जो अक्सर वेब फ्रेमवर्क में देखा जाता है।

स्पष्टीकरण: मिडलवेयर फ़ंक्शन अंतिम हैंडलर तक पहुंचने से पहले एक अनुरोध को संसाधित करते हैं। प्रत्येक मिडलवेयर अनुरोध/प्रतिक्रिया को संशोधित कर सकता है या नियंत्रण को अगले मिडलवेयर पर भेज सकता है। एक क्लास या ऑब्जेक्ट बनाएं जो मिडलवेयर फ़ंक्शंस की एक सूची का प्रबंधन करता है और उन्हें अनुक्रम में निष्पादित करता है।

class App { constructor() { this.middlewares = []; } use(fn) { this.middlewares.push(fn); } handle(request) { let index = 0; const next = () => { if (index < this.middlewares.length) { const middleware = this.middlewares[index++]; middleware(request, next); } }; next(); } } const app = new App(); app.use((req, next) => { console.log('1: लॉगिंग...'); req.logged = true; next(); }); app.use((req, next) => { console.log('2: प्रमाणीकरण...'); req.authed = true; next(); }); app.use((req, next) => { console.log('3: अंतिम हैंडलर:', req); }); app.handle({ data: 'कुछ अनुरोध' }); // 1: लॉगिंग... // 2: प्रमाणीकरण... // 3: अंतिम हैंडलर: { data: 'कुछ अनुरोध', logged: true, authed: true }

निर्देशित ग्राफ़ में चक्र का पता लगाएं

एक निर्देशित ग्राफ़ दिया गया है, यह निर्धारित करने के लिए एक फ़ंक्शन लिखें कि क्या इसमें एक चक्र है।

स्पष्टीकरण: डेप्थ-फर्स्ट सर्च (DFS) का उपयोग करें। दो सेट रखें: visiting (वर्तमान में रिकर्सन स्टैक में नोड्स) और visited (नोड्स जिन्हें पूरी तरह से खोजा गया है)। यदि आप DFS के दौरान visiting सेट में एक नोड पाते हैं, तो आपको एक बैक-एज मिल गया है, जिसका अर्थ है कि एक चक्र है।

function hasCycleDirected(graph) { const visiting = new Set(); const visited = new Set(); const nodes = Object.keys(graph); function dfs(node) { visiting.add(node); for (const neighbor of graph[node]) { if (visiting.has(neighbor)) return true; // चक्र का पता चला if (!visited.has(neighbor)) { if (dfs(neighbor)) return true; } } visiting.delete(node); visited.add(node); return false; } for (const node of nodes) { if (!visited.has(node)) { if (dfs(node)) return true; } } return false; } const cyclicGraph = { A: ['B'], B: ['C'], C: ['A'] }; const acyclicGraph = { A: ['B', 'C'], B: ['D'], C: ['E'], D: [], E: [] }; console.log(hasCycleDirected(cyclicGraph)); // true console.log(hasCycleDirected(acyclicGraph)); // false

`Object.freeze` का व्यवहार लागू करें

Object.freeze की व्याख्या करें और एक (उथला) संस्करण लागू करें।

स्पष्टीकरण: Object.freeze नई प्रॉपर्टीज को जोड़ने, मौजूदा प्रॉपर्टीज को हटाने और मौजूदा प्रॉपर्टीज या उनकी गणना क्षमता, कॉन्फ़िगरेशन क्षमता या लिखने की क्षमता को बदलने से रोकता है। यह एक ऑब्जेक्ट को अपरिवर्तनीय (उथला) बनाता है। आप इसे Object.preventExtensions और Object.defineProperty का उपयोग करके लागू कर सकते हैं ताकि मौजूदा प्रॉपर्टीज को न लिखा जा सके और न ही कॉन्फ़िगर किया जा सके।

function myFreeze(obj) { Object.preventExtensions(obj); // नई प्रॉपर्टीज जोड़ने से रोकें Object.keys(obj).forEach(key => { Object.defineProperty(obj, key, { writable: false, configurable: false }); }); return obj; } const obj = { a: 1, b: 2 }; myFreeze(obj); // obj.c = 3; // चुपचाप विफल (या सख्त मोड में एक त्रुटि फेंकता है) // delete obj.a; // चुपचाप विफल (या सख्त मोड में एक त्रुटि फेंकता है) // obj.a = 10; // चुपचाप विफल (या सख्त मोड में एक त्रुटि फेंकता है) console.log(obj); // { a: 1, b: 2 }

स्मूथ एनिमेशन के लिए `requestAnimationFrame` का उपयोग करें

requestAnimationFrame की व्याख्या करें और एक साधारण एनिमेशन लूप के लिए इसका उपयोग कैसे करें, यह दिखाएं।

स्पष्टीकरण: requestAnimationFrame (rAF) ब्राउज़र को बताता है कि आप एक एनिमेशन करना चाहते हैं और अगले रिपेंट से पहले एक एनिमेशन को अपडेट करने के लिए एक विशिष्ट फ़ंक्शन को कॉल करने का अनुरोध करता है। यह एनिमेशन के लिए setTimeout या setInterval का उपयोग करने की तुलना में अधिक कुशल और चिकना है, क्योंकि यह ब्राउज़र की ताज़ा दर के साथ सिंक्रनाइज़ करता है और जब टैब दिखाई नहीं देता है तो रुक जाता है।

// HTML: <div id='box' style='width: 50px; height: 50px; background: red; position: absolute; left: 0px;'></div> const box = document.getElementById('box'); let position = 0; let startTime = null; function animate(currentTime) { if (!startTime) startTime = currentTime; const elapsedTime = currentTime - startTime; // 2 सेकंड में 100px ले जाएँ (50px/सेकंड) position = (elapsedTime / 2000) * 100; if (position < 200) { // 200px तक पहुंचने तक एनिमेशन जारी रखें box.style.left = position + 'px'; requestAnimationFrame(animate); } else { box.style.left = '200px'; } } // एनिमेशन शुरू करें // requestAnimationFrame(animate); // ब्राउज़र में चलाने के लिए अनकमेंट करें console.log('ब्राउज़र एनिमेशन के लिए requestAnimationFrame का उपयोग करें।');

`Array.prototype.some` लागू करें

Array.prototype.some का अपना संस्करण लागू करें।

स्पष्टीकरण: some यह परीक्षण करता है कि सरणी में कम से कम एक तत्व प्रदान किए गए फ़ंक्शन द्वारा लागू किए गए परीक्षण को पास करता है या नहीं। यदि उसे कोई ऐसा तत्व मिलता है जिसके लिए कॉलबैक फ़ंक्शन true लौटाता है तो यह true लौटाता है; अन्यथा, यह false लौटाता है।

function mySome(arr, callback, thisArg) { for (let i = 0; i < arr.length; i++) { if (i in arr) { // विरल सरणियों को संभालें if (callback.call(thisArg, arr[i], i, arr)) { return true; } } } return false; } const arr = [1, 2, 3, 4, 5]; const hasEven = mySome(arr, x => x % 2 === 0); console.log(hasEven); // true

`Array.prototype.every` लागू करें

Array.prototype.every का अपना संस्करण लागू करें।

स्पष्टीकरण: every यह परीक्षण करता है कि सरणी में सभी तत्व प्रदान किए गए फ़ंक्शन द्वारा लागू किए गए परीक्षण को पास करते हैं या नहीं। यदि सभी तत्व पास होते हैं (या यदि सरणी खाली है) तो यह true लौटाता है, और यदि कोई तत्व विफल होता है तो false लौटाता है।

function myEvery(arr, callback, thisArg) { for (let i = 0; i < arr.length; i++) { if (i in arr) { if (!callback.call(thisArg, arr[i], i, arr)) { return false; } } } return true; } const arr1 = [1, 30, 39, 29, 10, 13]; const isBelow40 = myEvery(arr1, x => x < 40); console.log(isBelow40); // true const arr2 = [1, 30, 39, 29, 10, 45]; const isBelow40_2 = myEvery(arr2, x => x < 40); console.log(isBelow40_2); // false

`Array.prototype.findIndex` लागू करें

Array.prototype.findIndex का अपना संस्करण लागू करें।

स्पष्टीकरण: findIndex सरणी में पहले तत्व का इंडेक्स लौटाता है जो प्रदान किए गए परीक्षण फ़ंक्शन को संतुष्ट करता है। अन्यथा, यह -1 लौटाता है, यह दर्शाता है कि किसी भी तत्व ने परीक्षण पास नहीं किया।

function myFindIndex(arr, callback, thisArg) { for (let i = 0; i < arr.length; i++) { if (i in arr) { if (callback.call(thisArg, arr[i], i, arr)) { return i; } } } return -1; } const arr = [5, 12, 8, 130, 44]; const isLargeNumber = (element) => element > 13; console.log(myFindIndex(arr, isLargeNumber)); // 3

वेब वर्कर्स क्या हैं?

बताएं कि वेब वर्कर्स क्या हैं और उनका मुख्य उपयोग क्या है।

स्पष्टीकरण: वेब वर्कर्स वेब सामग्री के लिए पृष्ठभूमि थ्रेड्स में स्क्रिप्ट चलाने का एक साधन हैं। मुख्य उपयोग यूआई अपडेट और उपयोगकर्ता इंटरैक्शन को संभालने वाले मुख्य थ्रेड से लंबे समय तक चलने वाले या कम्प्यूटेशनल रूप से गहन कार्यों को ऑफलोड करना है, जिससे यूआई को अनुत्तरदायी या 'फ्रीज' होने से रोका जा सके। वर्कर्स मैसेज पासिंग (postMessage और onmessage) के माध्यम से मुख्य थ्रेड के साथ संवाद करते हैं।

// main.js /* if (window.Worker) { const myWorker = new Worker('worker.js'); myWorker.postMessage([5, 3]); // कार्यकर्ता को डेटा भेजें myWorker.onmessage = function(e) { console.log('कार्यकर्ता का परिणाम:', e.data); } } else { console.log('आपका ब्राउज़र वेब वर्कर्स का समर्थन नहीं करता है।'); } */ // worker.js /* self.onmessage = function(e) { console.log('मुख्य स्क्रिप्ट से संदेश प्राप्त हुआ'); const result = e.data[0] * e.data[1]; console.log('परिणाम मुख्य स्क्रिप्ट पर वापस पोस्ट किया जा रहा है'); self.postMessage(result); } */ console.log('वेब वर्कर्स पृष्ठभूमि थ्रेड्स में स्क्रिप्ट चलाते हैं।');

तरीकों को डीकोड करना

A-Z से अक्षर वाले संदेश को 'A' -> 1, 'B' -> 2, ..., 'Z' -> 26 मैपिंग का उपयोग करके संख्याओं में एन्कोड किया जा सकता है। केवल अंक वाली स्ट्रिंग s दिए जाने पर, इसे डीकोड करने के तरीकों की संख्या लौटाएं।

स्पष्टीकरण: डायनेमिक प्रोग्रामिंग का उपयोग करें। dp[i] को s[0...i-1] को डीकोड करने के तरीकों की संख्या होने दें। dp[i] dp[i-1] (यदि s[i-1] एक वैध 1-अंक कोड है) और dp[i-2] (यदि s[i-2...i-1] एक वैध 2-अंक कोड है) पर निर्भर करता है।

function numDecodings(s) { if (!s || s[0] === '0') return 0; const n = s.length; const dp = new Array(n + 1).fill(0); dp[0] = 1; dp[1] = 1; for (let i = 2; i <= n; i++) { const oneDigit = parseInt(s.substring(i - 1, i)); const twoDigits = parseInt(s.substring(i - 2, i)); if (oneDigit >= 1) { dp[i] += dp[i - 1]; } if (twoDigits >= 10 && twoDigits <= 26) { dp[i] += dp[i - 2]; } } return dp[n]; } console.log(numDecodings('12')); // 2 ('AB' या 'L') console.log(numDecodings('226')); // 3 ('BBF', 'BZ', 'VF') console.log(numDecodings('06')); // 0

बिटवाइज़ योग (`+` के बिना)

+ ऑपरेटर का उपयोग किए बिना दो पूर्णांकों को जोड़ने के लिए एक फ़ंक्शन लिखें।

स्पष्टीकरण: बिटवाइज़ ऑपरेटरों का उपयोग करें। योग की गणना a ^ b (बिना कैरी के योग) के रूप में की जा सकती है, और कैरी की गणना (a & b) << 1 के रूप में की जा सकती है। इस प्रक्रिया को तब तक दोहराएं जब तक कैरी 0 न हो जाए।

function getSum(a, b) { while (b !== 0) { const carry = (a & b) << 1; // कैरी की गणना करें a = a ^ b; // बिना कैरी के योग की गणना करें b = carry; // कैरी नया 'b' बन जाता है } return a; } console.log(getSum(3, 5)); // 8 console.log(getSum(-2, 3)); // 1

पैलिनड्रोम (संख्या) सत्यापित करें

एक पूर्णांक x दिए जाने पर, यदि x एक पैलिनड्रोम है तो true लौटाएं, अन्यथा false

स्पष्टीकरण: एक ऋणात्मक संख्या पैलिनड्रोम नहीं होती है। संख्या को एक स्ट्रिंग में कनवर्ट करें और जांचें कि क्या स्ट्रिंग एक पैलिनड्रोम है (आगे और पीछे से समान पढ़ता है)। वैकल्पिक रूप से, संख्या को गणितीय रूप से उलट दें और तुलना करें।

function isPalindromeNumber(x) { if (x < 0) return false; // स्ट्रिंग दृष्टिकोण // return String(x) === String(x).split('').reverse().join(''); // गणितीय दृष्टिकोण let original = x; let reversed = 0; while (x > 0) { reversed = reversed * 10 + (x % 10); x = Math.floor(x / 10); } return original === reversed; } console.log(isPalindromeNumber(121)); // true console.log(isPalindromeNumber(-121)); // false console.log(isPalindromeNumber(10)); // false

फ़ैक्टरी पैटर्न

जावास्क्रिप्ट में फ़ैक्टरी डिज़ाइन पैटर्न को लागू करें।

स्पष्टीकरण: फ़ैक्टरी पैटर्न एक सुपरक्लास में ऑब्जेक्ट बनाने के लिए एक इंटरफ़ेस प्रदान करता है, लेकिन सबक्लास को बनाए जाने वाले ऑब्जेक्ट के प्रकार को बदलने की अनुमति देता है। यह सटीक क्लास निर्दिष्ट किए बिना ऑब्जेक्ट बनाने के लिए उपयोगी है।

class Car { constructor(options) { this.type = 'कार'; this.doors = options.doors || 4; } } class Truck { constructor(options) { this.type = 'ट्रक'; this.bedSize = options.bedSize || 'लंबा'; } } class VehicleFactory { createVehicle(options) { if (options.vehicleType === 'car') { return new Car(options); } else if (options.vehicleType === 'truck') { return new Truck(options); } else { throw new Error('अज्ञात वाहन प्रकार'); } } } const factory = new VehicleFactory(); const car = factory.createVehicle({ vehicleType: 'car', doors: 2 }); const truck = factory.createVehicle({ vehicleType: 'truck', bedSize: 'छोटा' }); console.log(car); // Car { type: 'कार', doors: 2 } console.log(truck); // Truck { type: 'ट्रक', bedSize: 'छोटा' }

`Symbol` और एक उपयोग के मामले की व्याख्या करें

बताएं कि जावास्क्रिप्ट में Symbol क्या है और एक उपयोग का मामला प्रदान करें, जैसे 'निजी' गुण या अद्वितीय वस्तु कुंजियाँ बनाना।

स्पष्टीकरण: Symbol ES6 में पेश किया गया एक आदिम डेटा प्रकार है। इसकी इंस्टेंस अद्वितीय और अपरिवर्तनीय हैं। इन्हें अक्सर विभिन्न पुस्तकालयों के बीच नाम टकराव से बचने या छद्म-निजी गुण बनाने के लिए वस्तु गुणों के लिए कुंजी के रूप में उपयोग किया जाता है (हालांकि वे वास्तव में निजी नहीं हैं, वे विशिष्ट पुनरावृति या Object.keys के माध्यम से सुलभ नहीं हैं)।

const _privateName = Symbol('name'); const _privateMethod = Symbol('greet'); class Person { constructor(name) { this[_privateName] = name; } [_privateMethod]() { console.log(`नमस्ते, मेरा नाम ${this[_privateName]} है`); } introduce() { this[_privateMethod](); } } const p = new Person('बॉब'); p.introduce(); // नमस्ते, मेरा नाम बॉब है console.log(Object.keys(p)); // [] - सिंबल शामिल नहीं हैं console.log(p[_privateName]); // बॉब (यदि आपके पास सिंबल है तो सुलभ)

`arguments` को एक वास्तविक ऐरे में कनवर्ट करें

आप arguments ऑब्जेक्ट (गैर-एरो फ़ंक्शन में उपलब्ध) को एक वास्तविक जावास्क्रिप्ट ऐरे में कैसे कनवर्ट कर सकते हैं?

स्पष्टीकरण: arguments ऑब्जेक्ट एक ऐरे जैसा दिखता है लेकिन यह नहीं है; इसमें map, filter, आदि जैसे तरीकों की कमी है। आप इसे निम्न का उपयोग करके कनवर्ट कर सकते हैं:

  1. Array.from(arguments) (ES6)
  2. [...arguments] (ES6 स्प्रेड सिंटैक्स)
  3. Array.prototype.slice.call(arguments) (पुराना तरीका)
function sumAll() { // 1. Array.from const args1 = Array.from(arguments); console.log('Array.from का उपयोग करके:', args1.reduce((a, b) => a + b, 0)); // 2. स्प्रेड सिंटैक्स const args2 = [...arguments]; console.log('स्प्रेड का उपयोग करके:', args2.reduce((a, b) => a + b, 0)); // 3. स्लाइस const args3 = Array.prototype.slice.call(arguments); console.log('स्लाइस का उपयोग करके:', args3.reduce((a, b) => a + b, 0)); } sumAll(1, 2, 3, 4); // Array.from का उपयोग करके: 10 // स्प्रेड का उपयोग करके: 10 // स्लाइस का उपयोग करके: 10