Live Coding

چیک کریں کہ آیا کوئی آبجیکٹ خالی ہے

جاوا اسکرپٹ آبجیکٹ کے خالی ہونے کی جانچ کیسے کریں؟

وضاحت: ایک آبجیکٹ اس وقت خالی ہوتا ہے جب اس میں کوئی اپنی قابل شمار خصوصیات نہ ہوں۔ ہم 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 تک نمبرز پرنٹ کرتا ہے۔ لیکن تین کے ضربوں کے لیے، نمبر کے بجائے 'فز' پرنٹ کریں اور پانچ کے ضربوں کے لیے، 'بز' پرنٹ کریں۔ ایسے نمبروں کے لیے جو تین اور پانچ دونوں کے ضرب ہیں، 'فز بز' پرنٹ کریں۔

وضاحت: یہ کلاسک مسئلہ بنیادی لوپ اور کنڈیشنل منطق کو ٹیسٹ کرتا ہے۔ آپ کو 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 تک بڑھ جائیں۔

وضاحت: ایک عام طریقہ یہ ہے کہ ایک ہیش میپ (یا ایک جاوا اسکرپٹ آبجیکٹ) کا استعمال کریں تاکہ نمبروں اور ان کے انڈیکسز کو اسٹور کیا جا سکے جیسے ہی آپ لٹریشن کرتے ہیں۔ ہر نمبر کے لیے، جانچ کریں کہ آیا 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'

ارے چنکنگ

ایک فنکشن لکھیں جو ایک ارے کو ایک مخصوص سائز کے گروپوں میں تقسیم کرتا ہے۔

وضاحت: ارے میں لٹریشن کریں، مخصوص سائز کے ٹکڑے لیں اور انہیں ایک نئی ارے میں پش کریں۔ اس صورت حال کو سنبھالیں جہاں آخری چنک چھوٹا ہو سکتا ہے۔

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('Reduce of empty array with no initial value'); 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 (سامنے سے ہٹائیں) طریقوں کے ساتھ ایک قطار ڈیٹا ڈھانچہ کو لاگو کریں۔

وضاحت: ایک قطار First-In, First-Out (FIFO) اصول کی پیروی کرتی ہے۔ ایک ارے کو استعمال کیا جا سکتا ہے، جس میں 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 'قطار میں کوئی عناصر نہیں ہیں'; 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 (اوپر سے ہٹائیں) طریقوں کے ساتھ ایک اسٹیک ڈیٹا ڈھانچہ کو لاگو کریں۔

وضاحت: ایک اسٹیک Last-In, First-Out (LIFO) اصول کی پیروی کرتا ہے۔ ایک ارے کو استعمال کیا جا سکتا ہے، جس میں 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('ہیلو!'); 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('اسکرول ہو رہا ہے...'); 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

ایک آبجیکٹ کو گہرا کلون کریں

ایک جاوا اسکرپٹ آبجیکٹ کا گہرا کلون انجام دینے کے لیے ایک فنکشن لکھیں۔

وضاحت: ایک کم گہرا کلون صرف اوپری سطح کی خصوصیات کو کاپی کرتا ہے۔ ایک گہرا کلون تمام خصوصیات کو ریکرسیولی کاپی کرتا ہے، بشمول نیسٹڈ آبجیکٹس اور ایریز۔ ایک سادہ طریقہ (حدود کے ساتھ، مثلاً فنکشنز، تاریخوں، ریجیکس کو اچھی طرح سے ہینڈل نہیں کرتا) 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

آبجیکٹ کی کلیدیں حاصل کریں

ایک آبجیکٹ سے کلیدوں کی ایک ارے کیسے حاصل کریں؟

وضاحت: Object.keys(obj) استعمال کریں۔

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

آبجیکٹ کی قدریں حاصل کریں

ایک آبجیکٹ سے قدروں کی ایک ارے کیسے حاصل کریں؟

وضاحت: 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();

پراومس کیا ہے؟

جاوا اسکرپٹ میں پراومس کیا ہے اس کی وضاحت کریں۔

وضاحت: ایک پراومس ایک آبجیکٹ ہے جو ایک غیر ہم آہنگ آپریشن کی ممکنہ تکمیل (یا ناکامی) اور اس کی نتیجے والی ویلیو کی نمائندگی کرتا ہے۔ یہ تین حالتوں میں سے ایک میں ہو سکتا ہے: زیر التوا، مکمل، یا مسترد۔

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'

اریز میں اسپریڈ آپریٹر

اریز کے ساتھ اسپریڈ آپریٹر کیسے استعمال ہوتا ہے؟

وضاحت: یہ ایک لٹریبل (جیسے ایک ارے) کو ان جگہوں پر پھیلانے کی اجازت دیتا ہے جہاں صفر یا زیادہ آرگومنٹ یا عناصر کی توقع ہوتی ہے۔ کاپی کرنے، ضم کرنے، اور عناصر کو شامل کرنے کے لیے مفید ہے۔

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

آبجیکٹ میں اسپریڈ آپریٹر

آبجیکٹس کے ساتھ اسپریڈ آپریٹر کیسے استعمال ہوتا ہے؟

وضاحت: یہ آبجیکٹ کی خصوصیات کو کاپی کرنے اور ضم کرنے کی اجازت دیتا ہے۔

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' }, 'ہیلو', '!'); // ہیلو، چارلی!

`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' }, ['ہیلو', '.']); // ہیلو، ڈیوڈ۔

ایونٹ لوپ کی وضاحت کریں

جاوا اسکرپٹ ایونٹ لوپ کی مختصر وضاحت کریں۔

وضاحت: جاوا اسکرپٹ سنگل تھریڈڈ ہے، لیکن یہ ایک ایونٹ لوپ کا استعمال کرتے ہوئے ہم آہنگی حاصل کرتا ہے۔ کال اسٹیک ہم وقت ساز کوڈ کو ہینڈل کرتا ہے۔ ویب APIs async آپریشنز کو ہینڈل کرتی ہیں (جیسے setTimeout, fetch)۔ جب ایک async op ختم ہوتا ہے، تو اس کا کال بیک کال بیک کیو (یا پرومیسز کے لیے مائیکرو ٹاسک کیو) میں چلا جاتا ہے۔ ایونٹ لوپ مسلسل چیک کرتا ہے کہ آیا کال اسٹیک خالی ہے؛ اگر یہ خالی ہے، تو یہ اگلے کال بیک کو کیو سے اسٹیک میں ایگزیکیوشن کے لیے منتقل کر دیتا ہے۔

console.log('Start'); setTimeout(() => { console.log('Timeout Callback'); // Goes to Callback Queue }, 0); Promise.resolve().then(() => { console.log('Promise Resolved'); // Goes to Microtask Queue }); console.log('End'); // Output Order: Start, End, Promise Resolved, Timeout Callback // (Microtasks run before Macrotasks/Callbacks)

بائنری سرچ

ایک ترتیب شدہ صف کے لیے بائنری سرچ فنکشن نافذ کریں۔

وضاحت: بائنری سرچ ایک ترتیب شدہ صف میں کسی آئٹم کو تلاش کرنے کے لیے تلاش کے وقفے کو بار بار آدھا تقسیم کرکے موثر طریقے سے تلاش کرتا ہے۔ اگر تلاش کی کلید کی قدر وقفے کے بیچ میں موجود آئٹم سے کم ہے، تو وقفے کو نچلے نصف تک محدود کریں۔ بصورت دیگر، اسے اوپری نصف تک محدود کریں۔ آپ یہ اس وقت تک کرتے ہیں جب تک کہ قدر نہ مل جائے یا وقفہ خالی نہ ہو جائے۔

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; // Found } else if (sortedArray[middle] < key) { start = middle + 1; // Search right half } else { end = middle - 1; // Search left half } } return -1; // Not found } 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]]; // Swap swapped = true; } } n--; // Optimization: last element is already in place } 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 طریقوں کے ساتھ ایک سنگلی لنکڈ لسٹ نافذ کریں۔

وضاحت: ایک لنکڈ لسٹ ایک لکیری ڈیٹا ڈھانچہ ہے جہاں عناصر ملحقہ میموری مقامات پر ذخیرہ نہیں ہوتے ہیں۔ ہر عنصر (نوڈ) اگلے کی طرف اشارہ کرتا ہے۔ آپ کو ہیڈ اور نئے نوڈز کو شامل کرنے کے لیے ایک نوڈ کلاس اور ایک لنکڈ لسٹ کلاس کی ضرورت ہے۔

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; // Handle cases where k > length 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]

دو صفوں کا تقاطع معلوم کریں

دو صفیں دی گئی ہیں، ان کا تقاطع (دونوں میں مشترک عناصر) معلوم کرنے کے لیے ایک فنکشن لکھیں۔

وضاحت: ایک اچھا طریقہ یہ ہے کہ 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'])); // Output: [['eat', 'tea', 'ate'], ['tan', 'nat'], ['bat']]

صفروں کو آخر میں منتقل کریں

ایک صف nums دی گئی ہے، اس کے تمام 0s کو آخر میں منتقل کرنے کے لیے ایک فنکشن لکھیں جبکہ غیر صفر عناصر کی نسبتی ترتیب کو برقرار رکھیں۔

وضاحت: ٹو پوائنٹر یا سنو بال کا طریقہ استعمال کریں۔ ایک پوائنٹر اس پوزیشن کو ٹریک کرتا ہے جہاں اگلا غیر صفر عنصر جانا چاہیے۔ صف کے ذریعے دہرائیں؛ اگر کوئی عنصر غیر صفر ہے، تو اسے پوائنٹر کی پوزیشن پر رکھیں اور پوائنٹر کو بڑھائیں۔ آخر میں، باقی کو صفر سے بھریں۔

function moveZeroes(nums) { let nonZeroIndex = 0; // Move all non-zero elements to the front for (let i = 0; i < nums.length; i++) { if (nums[i] !== 0) { nums[nonZeroIndex] = nums[i]; nonZeroIndex++; } } // Fill the rest with zeros 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 (from [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)]; // Use Set to handle duplicate chars if needed } 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) { // Helper from previous problem 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

پرامس ڈاٹ آل نافذ کریں

ایک ایسا فنکشن نافذ کریں جو پرامس ڈاٹ آل کی طرح برتاؤ کرے۔

وضاحت: پرامس ڈاٹ آل پرامسز کی ایک صف لیتا ہے اور ایک سنگل پرامس واپس کرتا ہے جو اس وقت حل ہوتا ہے جب تمام ان پٹ پرامس حل ہو جاتے ہیں، یا اگر کوئی بھی ان پٹ پرامس رد ہو جاتا ہے تو رد ہو جاتا ہے۔ حل شدہ قدر حل شدہ قدروں کی ایک صف ہے۔

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); // Reject immediately on any error }); }); } // Example usage: 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; } // Swap the children [root.left, root.right] = [root.right, root.left]; // Recur for left and right children invertTree(root.left); invertTree(root.right); return root; } // Example: 4 -> [2, 7] -> [1, 3, 6, 9] // Becomes: 4 -> [7, 2] -> [9, 6, 3, 1]

بائنری ٹری کی زیادہ سے زیادہ گہرائی

ایک بائنری ٹری دی گئی ہے، اس کی زیادہ سے زیادہ گہرائی معلوم کریں۔

وضاحت: زیادہ سے زیادہ گہرائی روٹ نوڈ سے سب سے دور پتے کے نوڈ تک سب سے لمبے راستے پر نوڈز کی تعداد ہے۔ یہ بازگشتی طور پر پایا جا سکتا ہے: MaxDepth = 1 + max(MaxDepth(left), MaxDepth(right))۔ بیس کیس یہ ہے کہ جب ایک نوڈ null ہو، تو اس کی گہرائی 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; } // Example: 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

اسٹاک خریدنے/فروخت کرنے کا بہترین وقت

آپ کو ایک صف پرائسز دی گئی ہے جہاں پرائسز[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 (Buy at 1, Sell at 6) console.log(maxProfit([7, 6, 4, 3, 1])); // 0 (No profit possible)

اکیلا نمبر

غیر خالی اعداد کی صف 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); // Calculate prefix products let prefix = 1; for (let i = 0; i < n; i++) { answer[i] = prefix; prefix *= nums[i]; } // Calculate suffix products and multiply with prefix 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]

جزیروں کی تعداد

1s (زمین) اور 0s (پانی) کے 2D گرڈ میپ دیئے گئے ہیں، جزیروں کی تعداد شمار کریں۔ ایک جزیرہ پانی سے گھرا ہوا ہے اور ملحقہ زمینوں کو افقی یا عمودی طور پر جوڑ کر بنتا ہے۔

وضاحت: گرڈ کے ہر سیل کے ذریعے دہرائیں۔ اگر آپ کو '1' (زمین) ملتا ہے، تو جزیرے کی گنتی میں اضافہ کریں اور اس سیل سے ڈیپتھ فرسٹ سرچ (DFS) یا بریڈتھ فرسٹ سرچ (BFS) شروع کریں۔ تلاش کے دوران، تمام منسلک '1s' کو '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'; // Mark as visited 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 (Need to run on a copy or restore grid)

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); // Remove to re-insert at the 'end' (most recent) 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); // Evicts 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; // Skip duplicates for 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++; // Skip duplicates while (left < right && nums[right] === nums[right - 1]) right--; // Skip duplicates 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; // If not found, start is the insertion point } 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; } // Example: 1->2->4 and 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); } // Example: 1 -> [2, 2] -> [3, 4, 4, 3] is symmetric.

لیول آرڈر ٹریورسل (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; } // Example: 3 -> [9, 20] -> [null, null, 15, 7] // Output: [[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); } // Example: [-10, -3, 0, 5, 9] // Output: A tree like [0, -3, 9, -10, null, 5, null]

بائنڈ نافذ کریں

Function.prototype.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 is global/window) const boundGetX = unboundGetX.myBind(module); console.log(boundGetX()); // 42

Kth سب سے بڑا عنصر معلوم کریں

ایک غیر ترتیب شدہ صف میں kth سب سے بڑا عنصر معلوم کریں۔ نوٹ کریں کہ یہ ترتیب شدہ ترتیب میں kth سب سے بڑا عنصر ہے، kth الگ عنصر نہیں۔

وضاحت: ایک سادہ طریقہ یہ ہے کہ صف کو ترتیب دیں اور پھر انڈیکس n - k پر موجود عنصر کو چنیں۔ بڑی صفوں کے لیے ایک زیادہ موثر طریقہ میں ایک من ہپ یا Quickselect جیسا انتخاب الگورتھم شامل ہے۔

function findKthLargest(nums, k) { // Simple approach: Sort nums.sort((a, b) => b - a); // Sort in descending order return nums[k - 1]; // Note: Quickselect would be more efficient in an interview // but sorting is easier to implement quickly. } 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

چیک کریں کہ آیا آبجیکٹ میں پراپرٹی ہے

آپ کیسے چیک کر سکتے ہیں کہ آیا ایک آبجیکٹ میں ایک مخصوص پراپرٹی ہے؟

وضاحت: آپ ان آپریٹر (اپنی اور وراثت میں ملی پراپرٹیز کو چیک کرتا ہے)، Object.prototype.hasOwnProperty.call(obj, prop) (صرف اپنی پراپرٹیز کو چیک کرتا ہے)، یا محض obj.prop !== undefined (undefined قدروں کے ساتھ مشکل ہو سکتا ہے) استعمال کر سکتے ہیں۔

const person = { name: 'Eve', age: 28 }; function hasProp(obj, prop) { console.log(`Using 'in': ${prop in obj}`); console.log(`Using 'hasOwnProperty': ${Object.prototype.hasOwnProperty.call(obj, prop)}`); } hasProp(person, 'name'); // true, true hasProp(person, 'toString'); // true, false (toString is inherited)

انٹیجر سے رومن

ایک فنکشن لکھیں جو ایک انٹیجر کو اس کی رومن عددی نمائندگی میں تبدیل کرے۔

وضاحت: رومن اعداد اور ان کی متعلقہ قدروں کی ایک میپ بنائیں، جو سب سے بڑے سے سب سے چھوٹے تک ترتیب دی گئی ہو۔ اس میپ کے ذریعے دہرائیں۔ ہر قدر کے لیے، اسے ان پٹ نمبر سے زیادہ سے زیادہ بار گھٹائیں، ہر بار رومن عدد کو شامل کرتے ہوئے۔

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

ایک سیٹ نافذ کریں

ایک بنیادی سیٹ ڈیٹا ڈھانچہ (بلٹ ان سیٹ کا استعمال کیے بغیر) add، has، delete، اور size طریقوں کے ساتھ نافذ کریں۔

وضاحت: آپ بنیادی ذخیرہ کے طور پر جاوا اسکرپٹ آبجیکٹ (ہیش میپ) استعمال کر سکتے ہیں۔ کیز سیٹ کے عناصر ہوں گی (آپ کو یہ ہینڈل کرنے کی ضرورت ہو سکتی ہے کہ مختلف اقسام کو کیسے ذخیرہ کیا جائے اور کیز کے طور پر انفرادیت کو یقینی بنایا جائے)۔

class MySet { constructor() { this.items = {}; this._size = 0; } add(element) { if (!this.has(element)) { this.items[element] = element; // Store the 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; // Word found if (r < 0 || c < 0 || r >= rows || c >= cols || board[r][c] !== word[index]) { return false; } const temp = board[r][c]; board[r][c] = '#'; // Mark as visited 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; // Backtrack 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'

لنکڈ لسٹ کو الٹا کریں

ایک واحد لنکڈ لسٹ کا ہیڈ دیا گیا ہے، فہرست کو الٹا کریں، اور الٹا کردہ فہرست واپس کریں۔

وضاحت: آپ کو فہرست کے ذریعے دہرانا ہوگا، ہر نوڈ کے 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; // Store next node current.next = prev; // Reverse current node's pointer prev = current; // Move prev one step forward current = next; // Move current one step forward } return prev; // New head is the last 'prev' } // Example: 1->2->3->4->5 becomes 5->4->3->2->1

لنکڈ لسٹ میں سائیکل کا پتہ لگائیں

ہیڈ، ایک لنکڈ لسٹ کا ہیڈ دیا گیا ہے، معلوم کریں کہ آیا لنکڈ لسٹ میں کوئی سائیکل ہے یا نہیں۔

وضاحت: فلائیڈز ٹورٹوائز اور ہیر الگورتھم استعمال کریں۔ دو پوائنٹرز رکھیں، ایک ایک وقت میں ایک قدم (سلو) چلتا ہے اور ایک ایک وقت میں دو قدم (تیز) چلتا ہے۔ اگر کوئی سائیکل ہے، تو تیز پوائنٹر آخر کار سلو پوائنٹر کو پکڑ لے گا۔

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; // Reached end, no cycle slow = slow.next; fast = fast.next.next; } return true; // Pointers met, cycle exists } // Example: 3->2->0->-4 with -4 pointing back to 2. hasCycle returns true.

Object.create کو نافذ کریں

ایک ایسا فنکشن نافذ کریں جو Object.create(proto) کے طرز عمل کی نقل کرے۔

وضاحت: Object.create ایک نیا آبجیکٹ بناتا ہے، موجودہ آبجیکٹ کو نئے بنائے گئے آبجیکٹ کے پروٹو ٹائپ کے طور پر استعمال کرتا ہے۔ آپ اسے ایک عارضی کنسٹرکٹر فنکشن بنا کر، اس کے پروٹو ٹائپ کو ان پٹ پروٹو پر سیٹ کر کے، اور پھر اس کی ایک نئی مثال واپس کر کے حاصل کر سکتے ہیں۔

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(`My name is ${this.name}. Am I human? ${this.isHuman}`); } }; const me = myObjectCreate(person); me.name = 'Matthew'; me.isHuman = true; me.printIntroduction(); // My name is Matthew. Am I human? true console.log(Object.getPrototypeOf(me) === person); // true

Hoisting کیا ہے؟

جاوا اسکرپٹ میں ہوسٹنگ کی وضاحت کریں اور ایک مثال فراہم کریں۔

وضاحت: ہوسٹنگ جاوا اسکرپٹ کا ڈیفالٹ طرز عمل ہے جس میں اعلانات کو کوڈ کے عمل سے پہلے موجودہ اسکوپ (گلوبل یا فنکشن) کے اوپری حصے میں منتقل کرنا ہے۔ متغیر اعلانات (var) کو ہوسٹ کیا جاتا ہے اور undefined کے ساتھ ابتدائی بنایا جاتا ہے۔ فنکشن کے اعلانات کو مکمل طور پر ہوسٹ کیا جاتا ہے (نام اور باڈی دونوں)۔ let اور const کو ہوسٹ کیا جاتا ہے لیکن ابتدائی نہیں کیا جاتا، جس سے Temporal Dead Zone پیدا ہوتا ہے۔

console.log(myVar); // undefined (var is hoisted and initialized with undefined) // console.log(myLet); // ReferenceError: Cannot access 'myLet' before initialization (TDZ) myFunc(); // 'Hello!' (Function declaration is fully hoisted) var myVar = 'I am a var'; let myLet = 'I am a let'; function myFunc() { console.log('Hello!'); }

ایونٹ ببلنگ اور کیپچرنگ کی وضاحت کریں

DOM کے تناظر میں ایونٹ ببلنگ اور کیپچرنگ کی وضاحت کریں۔

وضاحت: یہ HTML DOM میں ایونٹ پروپیگیشن کے دو مراحل ہیں۔ کیپچرنگ مرحلہ: ایونٹ ونڈو سے ٹارگٹ عنصر تک نیچے سفر کرتا ہے۔ ببلنگ مرحلہ: ایونٹ ٹارگٹ عنصر سے ونڈو تک اوپر سفر کرتا ہے۔ ڈیفالٹ طور پر، زیادہ تر ایونٹ ہینڈلرز ببلنگ مرحلے کے دوران رجسٹر ہوتے ہیں۔ آپ کیپچرنگ مرحلے کے دوران ایونٹس کو ہینڈل کرنے کے لیے addEventListener(type, listener, useCapture) کو useCapture = true کے ساتھ استعمال کر سکتے ہیں۔

// In an HTML structure: <div><p><span>Click Me</span></p></div> // If you click the <span>: // Capturing: window -> document -> html -> body -> div -> p -> span // Bubbling: span -> p -> div -> body -> html -> document -> window /* JS Example div.addEventListener('click', () => console.log('Div clicked'), true); // Capturing p.addEventListener('click', () => console.log('P clicked'), false); // Bubbling span.addEventListener('click', () => console.log('Span clicked'), false); // Bubbling // Output would be: Div clicked, Span clicked, P clicked */

JSON.parse کو دستی طور پر نافذ کریں (بنیادی)

JSON.parse کا ایک بہت بنیادی ورژن نافذ کرنے کی کوشش کریں (سادہ آبجیکٹس، صفوں، سٹرنگز، نمبروں کو ہینڈل کریں)۔

وضاحت: یہ مکمل طور پر ایک بہت پیچیدہ کام ہے، لیکن لائیو کوڈنگ کی ترتیب کے لیے، آپ کو بہت آسان ذیلی سیٹ کو ہینڈل کرنے کے لیے کہا جا سکتا ہے۔ آپ کو سٹرنگ کو پارس کرنے کی ضرورت ہوگی، آبجیکٹ {} اور اری [] کی حدود، کلیدی-قدر کے جوڑوں (کنجی: قدر)، اور بنیادی ڈیٹا کی اقسام کی شناخت کرنا۔ eval یا new Function اس میں دھوکہ دے سکتے ہیں لیکن خطرناک ہیں۔ ایک حقیقی پارسر ایک لیکسر/ٹاکنائزر اور پارسر استعمال کرے گا۔

function basicJsonParse(jsonString) { // WARNING: Using new Function is insecure like eval. // This is a simplified, INSECURE example for demonstration only. // A real implementation requires a proper parser. try { return (new Function('return ' + jsonString))(); } catch (e) { throw new SyntaxError('Invalid JSON: ' + e.message); } } console.log(basicJsonParse('{"a": 1, "b": ["x", "y"]}')); // { a: 1, b: ['x', 'y'] }

ایک گہری نیسٹڈ صف کو فلیٹ کریں

ایک گہری نیسٹڈ صف کو فلیٹ کرنے کے لیے ایک فنکشن لکھیں۔

وضاحت: پچھلے فلیٹ (ایک لیول) کے برعکس، اسے نیسٹنگ کے کسی بھی لیول کو ہینڈل کرنے کی ضرورت ہے۔ بازگشت ایک قدرتی فٹ ہے۔ صف کے ذریعے دہرائیں۔ اگر کوئی عنصر ایک صف ہے، تو اس پر بازگشتی طور پر فلیٹ کال کریں اور نتیجہ کو جوڑیں۔ بصورت دیگر، عنصر شامل کریں۔

function deepFlatten(arr) { let flattened = []; arr.forEach(item => { if (Array.isArray(item)) { flattened = flattened.concat(deepFlatten(item)); } else { flattened.push(item); } }); return flattened; // ES2019+ provides a much simpler way: // 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('apple'); console.log(trie.search('apple')); // true console.log(trie.search('app')); // false console.log(trie.startsWith('app')); // 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]]; // Swap elements } return arr; } console.log(shuffleArray([1, 2, 3, 4, 5])); // e.g., [3, 5, 1, 2, 4]

افعال کو کمپوز کریں

ایک کمپوز فنکشن نافذ کریں جو متعدد فنکشنز لیتا ہے اور ایک نیا فنکشن واپس کرتا ہے جو انہیں دائیں سے بائیں لگاتا ہے۔

وضاحت: فنکشن کمپوزیشن (f ∘ g)(x) = f(g(x)) ایک فنکشن کو دوسرے کے نتیجے پر لاگو کرتی ہے۔ ایک عام کمپوز(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

پائپ فنکشنز

ایک پائپ فنکشن نافذ کریں جو متعدد فنکشنز لیتا ہے اور ایک نیا فنکشن واپس کرتا ہے جو انہیں بائیں سے دائیں لگاتا ہے۔

وضاحت: کمپوز کی طرح، لیکن اطلاق کی ترتیب الٹی ہے: پائپ(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 - coin]) + 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; // Found LCA } } return null; // Should not happen in a valid BST with p and q } // Example: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 => LCA is 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(); } // Example: 1 -> [2, 3] -> [null, null, 4, 5] // Serialized: '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(); // Schedule the next call }, delay); } run(); return interval; // Return an object to allow clearing } function myClearInterval(interval) { clearTimeout(interval.timerId); } // Example usage: let count = 0; const intervalId = mySetInterval(() => { console.log(`Hello: ${++count}`); if (count === 3) myClearInterval(intervalId); }, 500);

گراف ٹریورسل (BFS اور DFS)

دیئے گئے گراف کے لیے بریڈتھ-فرسٹ سرچ (BFS) اور ڈیپتھ-فرسٹ سرچ (DFS) نافذ کریں۔ (adjacency list representation)۔

وضاحت: 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); // Add neighbors in reverse to process them in order later (optional) 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; // Transpose 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]]; } } // Reverse each row 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]]

Spiral Matrix Traversal

ایک $m \times 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]

Set Matrix Zeroes

ایک $m \times n$ میٹرکس دی گئی ہے، اگر کوئی عنصر 0 ہے، تو اس کی پوری قطار اور کالم کو 0 پر سیٹ کریں۔ اسے ان-پلیس کریں۔

وضاحت: ایک سادہ طریقہ کار کو $O(m \times 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; } // Example: [[1,1,1],[1,0,1],[1,1,1]] => [[1,0,1],[0,0,0],[1,0,1]]

Implement `Promise.race`

Promise.race کی طرح برتاؤ کرنے والا فنکشن لاگو کریں۔

وضاحت: Promise.race پرامیسز کا ایک صف لیتا ہے اور ایک واحد پرامیس واپس کرتا ہے۔ یہ واپس کیا گیا پرامیس جیسے ہی کسی بھی ان پٹ پرامیسز کا فیصلہ ہو جاتا ہے (ریزولول یا ریجیکٹ ہوتا ہے)، اس پرامیس کی قدر یا وجہ کے ساتھ طے ہو جاتا ہے۔

function myPromiseRace(promises) { return new Promise((resolve, reject) => { if (!promises || promises.length === 0) { return; // Or resolve/reject depending on spec } promises.forEach(promise => { Promise.resolve(promise).then(resolve, reject); }); }); } const p1 = new Promise((resolve) => setTimeout(resolve, 500, 'one')); const p2 = new Promise((resolve) => setTimeout(resolve, 100, 'two')); myPromiseRace([p1, p2]).then(value => console.log(value)); // 'two'

Singleton Pattern

جاوا اسکرپٹ میں سنگلٹن ڈیزائن پیٹرن لاگو کریں۔

وضاحت: سنگلٹن پیٹرن اس بات کو یقینی بناتا ہے کہ ایک کلاس کا صرف ایک ہی مثال ہو اور اس تک رسائی کا ایک عالمی نقطہ فراہم کرتا ہے۔ یہ مثال کو رکھنے کے لیے کلوزر کا استعمال کرتے ہوئے حاصل کیا جا سکتا ہے۔

const Singleton = (function() { let instance; function createInstance() { // Private methods and variables const privateVar = 'I am private'; function privateMethod() { console.log('Private'); } return { // Public methods and variables publicVar: 'I am public', publicMethod: function() { console.log('Public'); }, 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()); // 'I am private'

Validate IP Address

یہ جانچنے کے لیے ایک فنکشن لکھیں کہ آیا دی گئی سٹرنگ ایک درست 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; // Simplified: No '::' 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 (Simplified) console.log(validIPAddress('256.256.256.256')); // Neither

Find Peak Element

ایک چوٹی کا عنصر ایک ایسا عنصر ہے جو اپنے پڑوسیوں سے سختی سے بڑا ہے۔ دی گئی ان پٹ ارے 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; // Peak is to the right } else { right = mid; // Peak is mid or to the left } } return left; // 'left' will be the index of a peak } console.log(findPeakElement([1, 2, 3, 1])); // 2 (index of 3) console.log(findPeakElement([1, 2, 1, 3, 5, 6, 4])); // 5 (index of 6) or 1 (index of 2)

Counting Bits

ایک عدد 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)، اگر i طاق ہے تو 1 کے علاوہ۔

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); // Or: dp[i] = dp[i & (i - 1)] + 1; (Removes last set bit) } return dp; } console.log(countBits(5)); // [0, 1, 1, 2, 1, 2]

Power of Two

ایک عدد 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

Merge Intervals

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]) { // Overlap: merge last[1] = Math.max(last[1], current[1]); } else { // No overlap: add new interval merged.push(current); } } return merged; } console.log(mergeIntervals([[1, 3], [2, 6], [8, 10], [15, 18]])); // [[1, 6], [8, 10], [15, 18]]

Word Break

ایک سٹرنگ s اور سٹرنگز کی ایک ڈکشنری wordDict دی گئی ہے، اگر s کو ایک یا زیادہ ڈکشنری الفاظ کی جگہ سے الگ کردہ ترتیب میں تقسیم کیا جا سکتا ہے تو true واپس کریں، بصورت دیگر false۔

وضاحت: ڈائنامک پروگرامنگ کا استعمال کریں۔ ایک بولین ارے 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; // Base case: empty string 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

Implement `Array.prototype.flat`

Array.prototype.flat کا اپنا ورژن لاگو کریں، جو تمام سب-ارے عناصر کو مخصوص گہرائی تک ریکرسیو طور پر جوڑ کر ایک نیا ارے بناتا ہے۔

وضاحت: ریکرشن کا استعمال کریں۔ ارے کے ذریعے دہرائیں۔ اگر کوئی عنصر ایک ارے ہے اور موجودہ گہرائی مخصوص گہرائی سے کم ہے، تو اس پر فلیٹ کو ریکرسیو طور پر کال کریں۔ بصورت دیگر، عنصر کو پش کریں۔ 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]

Reverse Words in a String

ایک ان پٹ سٹرنگ s دی گئی ہے، الفاظ کی ترتیب کو الٹ دیں۔

وضاحت: ایک 'لفظ' کو نان-سپیس حروف کے ایک ترتیب کے طور پر تعریف کیا گیا ہے۔ سٹرنگ کو ٹرم کریں، اسے ایک یا زیادہ سپیسز سے الگ کریں، متعدد سپیسز سے نتیجے میں آنے والی کسی بھی خالی سٹرنگ کو فلٹر کریں، ارے کو الٹ دیں، اور اسے ایک ہی سپیسز کے ساتھ واپس جوڑ دیں۔

function reverseWords(s) { return s.trim().split(/\s+/).reverse().join(' '); } console.log(reverseWords('the sky is blue')); // 'blue is sky the' console.log(reverseWords(' hello world ')); // 'world hello' console.log(reverseWords('a good example')); // 'example good a'

Query String Parser

ایک فنکشن لکھیں جو 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 }

Use `Proxy` for Validation

آبجیکٹ پراپرٹی کی توثیق کے لیے Proxy آبجیکٹ کا استعمال کیسے کریں اس کا مظاہرہ کریں۔

وضاحت: ایک Proxy آپ کو کسی آبجیکٹ پر کیے جانے والے آپریشنز کو روکنے اور اپنی مرضی کے مطابق بنانے کی اجازت دیتا ہے۔ کسی پراپرٹی کو تفویض کرنے سے پہلے اقدار کی توثیق کرنے کے لیے set ٹریپ کا استعمال کریں۔ اگر توثیق ناکام ہو جاتی ہے تو ایک ایرر تھرو کریں۔

const validator = { set: function(obj, prop, value) { if (prop === 'age') { if (!Number.isInteger(value)) { throw new TypeError('The age is not an integer'); } if (value < 0 || value > 150) { throw new RangeError('The age seems invalid'); } } // Default behavior: Set the property obj[prop] = value; return true; } }; const person = {}; const personProxy = new Proxy(person, validator); personProxy.age = 30; // OK console.log(personProxy.age); // 30 // personProxy.age = 'thirty'; // Throws TypeError // personProxy.age = 200; // Throws RangeError

Meeting Rooms

میٹنگ کے اوقات کے وقفوں کی ایک صف [[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; // Overlap detected } } return true; } console.log(canAttendMeetings([[0, 30], [5, 10], [15, 20]])); // false (5<30) console.log(canAttendMeetings([[7, 10], [2, 4]])); // true

Implement `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([], 'All promises were rejected')); return; } let rejectionCount = 0; const errors = []; promises.forEach((promise, index) => { Promise.resolve(promise) .then(resolve) // Resolve as soon as one fulfills .catch(error => { errors[index] = error; rejectionCount++; if (rejectionCount === numPromises) { reject(new AggregateError(errors, 'All promises were rejected')); } }); }); }); } // Example: myPromiseAny([Promise.reject('err1'), Promise.resolve('ok')]) -> 'ok' // Example: myPromiseAny([Promise.reject('err1'), Promise.reject('err2')]) -> AggregateError

Observer Pattern

جاوا اسکرپٹ میں آبزرور (پب/سب) ڈیزائن پیٹرن لاگو کریں۔

وضاحت: آبزرور پیٹرن آبجیکٹس کے درمیان ایک سے کئی تعلق کی وضاحت کرتا ہے۔ جب ایک آبجیکٹ (سبجیکٹ) کی حالت بدلتی ہے، تو اس کے تمام انحصار (آبزرورز) کو خود بخود مطلع کیا جاتا ہے اور اپ ڈیٹ کیا جاتا ہے۔ سبجیکٹ آبزرورز کی ایک فہرست کو برقرار رکھتا ہے اور انہیں شامل کرنے، ہٹانے اور مطلع کرنے کے طریقے فراہم کرتا ہے۔

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} received: ${data}`); } } const subject = new Subject(); const obs1 = new Observer('Observer 1'); const obs2 = new Observer('Observer 2'); subject.subscribe(obs1); subject.subscribe(obs2); subject.notify('Something happened!'); // Observer 1 received: Something happened! // Observer 2 received: Something happened!

Find Duplicate Number

ایک عددوں کا ارے nums دیا گیا ہے جس میں n + 1 اعداد شامل ہیں جہاں ہر عدد [1, n] رینج میں شامل ہے، ایک دہرایا گیا نمبر تلاش کریں۔

وضاحت: چونکہ اعداد [1, n] میں ہیں اور ارے کا سائز n+1 ہے، یہ کم از کم ایک نقل کی ضمانت دیتا ہے۔ اسے 'لنکڈ لسٹ میں سائیکل تلاش کریں' کے مسئلے (فلوئیڈ کا ٹورٹوائز اور ہیر) سے نقش کیا جا سکتا ہے۔ ارے کی اقدار کو پوائنٹرز کے طور پر سمجھیں: index -> nums[index]۔

function findDuplicate(nums) { let tortoise = nums[0]; let hare = nums[0]; // Phase 1: Find the intersection point do { tortoise = nums[tortoise]; hare = nums[nums[hare]]; } while (tortoise !== hare); // Phase 2: Find the entrance to the cycle 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

Basic HTML Sanitizer

ایک بنیادی فنکشن لکھیں جو ایک HTML سٹرنگ کو سینیٹائز کرے، ممکنہ طور پر نقصان دہ ٹیگز (جیسے <script>) کو ہٹائے جبکہ محفوظ ٹیگز (جیسے <p>, <b>) کو برقرار رکھے۔

وضاحت: یہ ایک پیچیدہ موضوع ہے، اور حقیقی دنیا کے سینیٹائزر نفیس ہوتے ہیں۔ ایک انٹرویو کے لیے، ایک بنیادی طریقہ کار میں مخصوص ٹیگز کو ہٹانے کے لیے ریجیکس کا استعمال یا صرف ٹیگز کی وائٹ لسٹ کی اجازت دینا شامل ہو سکتا ہے۔ یہ پروڈکشن کے لیے محفوظ نہیں ہے۔

function basicSanitize(html) { // WARNING: This is a very basic and insecure example. // Do NOT use this in production. Use a library like DOMPurify. // Remove script tags let sanitized = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, ''); // Example: Remove onclick attributes (very basic) sanitized = sanitized.replace(/\s(on\w+)=['"]?[^'"]*['"]?/gi, ''); return sanitized; } console.log(basicSanitize('<p>Hello <script>alert("XSS")</script> <b onclick="danger()">World</b></p>')); // <p>Hello <b >World</b></p>

Edit Distance

دو سٹرنگز 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, // Deletion dp[i][j - 1] + 1, // Insertion dp[i - 1][j - 1] + cost // Substitution/Match ); } } return dp[m][n]; } console.log(minDistance('horse', 'ros')); // 3 console.log(minDistance('intention', 'execution')); // 5

Longest Increasing Subsequence (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-Queens Problem

N-Queens پزل N \times 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; // Check col for (let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) if (board[i][j] === 'Q') return false; // Check diag up-left for (let i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) if (board[i][j] === 'Q') return false; // Check diag up-right 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 } } } backtrack(0); return results; } console.log(solveNQueens(4)); // [ [ '.Q..', '...Q', 'Q...', '..Q.' ], [ '..Q.', 'Q...', '...Q', '.Q..' ] ]

Use `WeakMap` for Private Data

کلاس انسٹینسز کے لیے نجی ڈیٹا کو ذخیرہ کرنے کے لیے 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('Alice', 30); console.log(person.getName()); // Alice person.celebrateBirthday(); console.log(person.getAge()); // 31 // console.log(person.name); // undefined - 'name' isn't a public property // console.log(privateData.get(person)); // Accessible, but not directly via 'person.'

Implement `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); } }); }); }); } // Example: myPromiseAllSettled([Promise.resolve(1), Promise.reject('err')]) // -> [{status: 'fulfilled', value: 1}, {status: 'rejected', reason: 'err'}]

Find the Median of Two Sorted Arrays

دو ترتیب شدہ اریز nums1 اور nums2 دی گئی ہیں جن کا سائز بالترتیب m اور n ہے، دونوں ترتیب شدہ اریز کا میڈین واپس کریں۔

وضاحت: یہ ایک مشکل مسئلہ ہے جو اکثر چھوٹے ارے پر بائنری سرچ کے طریقے سے حل کیا جاتا ہے۔ مقصد دونوں اریز کو اس طرح تقسیم کرنا ہے کہ بائیں طرف کے تمام عناصر دائیں طرف کے تمام عناصر سے کم یا برابر ہوں، اور بائیں طرف کے عناصر کی تعداد دائیں کے برابر (یا ایک زیادہ) ہو۔ میڈین کا حساب پھر باؤنڈری عناصر سے کیا جا سکتا ہے۔

function findMedianSortedArrays(nums1, nums2) { if (nums1.length > nums2.length) [nums1, nums2] = [nums2, nums1]; // Ensure nums1 is smaller 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('Input arrays are not sorted'); } console.log(findMedianSortedArrays([1, 3], [2])); // 2.0 console.log(findMedianSortedArrays([1, 2], [3, 4])); // 2.5

Sudoku Solver

خالی سیلز کو بھر کر سوڈوکو پزل کو حل کرنے کے لیے ایک پروگرام لکھیں۔

وضاحت: بیک ٹریکنگ کا استعمال کریں۔ ایک خالی سیل تلاش کریں۔ اسے 1 سے 9 تک کے اعداد سے بھرنے کی کوشش کریں۔ ہر عدد کے لیے، چیک کریں کہ آیا یہ درست ہے (سوڈوکو قوانین کی خلاف ورزی نہیں کرتا)۔ اگر درست ہے، تو سولور کو ریکرسیو طور پر کال کریں۔ اگر ریکرشن صحیح واپس کرتا ہے، تو ایک حل مل جاتا ہے۔ اگر نہیں، تو بیک ٹریک کریں (سیل کو دوبارہ سیٹ کریں) اور اگلے عدد کی کوشش کریں۔

function solveSudoku(board) { function isValid(row, col, numStr) { for (let i = 0; i < 9; i++) { if (board[row][i] === numStr) return false; // Check row if (board[i][col] === numStr) return false; // Check col 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; // Check box } 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] = '.'; // Backtrack } } return false; // No valid number found } } } return true; // Board solved } backtrack(); return board; } // Example requires a 9x9 board with '.' for empty cells.

Implement a Basic Middleware Pattern

ویب فریم ورکس میں اکثر دیکھے جانے والے ایک سادہ مڈل ویئر پیٹرن کو لاگو کریں۔

وضاحت: مڈل ویئر فنکشنز حتمی ہینڈلر تک پہنچنے سے پہلے ایک درخواست کو پروسیس کرتے ہیں۔ ہر مڈل ویئر درخواست/جواب کو تبدیل کر سکتا ہے یا next مڈل ویئر کو کنٹرول دے سکتا ہے۔ ایک کلاس یا آبجیکٹ بنائیں جو مڈل ویئر فنکشنز کی فہرست کا انتظام کرتا ہے اور انہیں ترتیب میں چلاتا ہے۔

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: Logging...'); req.logged = true; next(); }); app.use((req, next) => { console.log('2: Authenticating...'); req.authed = true; next(); }); app.use((req, next) => { console.log('3: Final Handler:', req); }); app.handle({ data: 'some request' }); // 1: Logging... // 2: Authenticating... // 3: Final Handler: { data: 'some request', logged: true, authed: true }

Detect Cycle in Directed Graph

ایک ڈائریکٹڈ گراف دیا گیا ہے، یہ تعین کرنے کے لیے ایک فنکشن لکھیں کہ آیا اس میں سائیکل موجود ہے۔

وضاحت: ڈیپتھ فرسٹ سرچ (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; // Cycle detected 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

Implement `Object.freeze` behavior

Object.freeze کی وضاحت کریں اور ایک (اتھلا) ورژن لاگو کریں۔

وضاحت: Object.freeze نئی خصوصیات شامل کرنے، موجودہ خصوصیات کو ہٹانے، اور موجودہ خصوصیات یا ان کی گنتی، ترتیب، یا لکھنے کی اہلیت کو تبدیل کرنے سے روکتا ہے۔ یہ کسی آبجیکٹ کو ناقابل تغیر (اتھلا) بناتا ہے۔ آپ اسے Object.preventExtensions اور Object.defineProperty کا استعمال کرتے ہوئے لاگو کر سکتے ہیں تاکہ موجودہ خصوصیات کو غیر تحریری اور غیر ترتیب پذیر بنایا جا سکے۔

function myFreeze(obj) { Object.preventExtensions(obj); // Prevent adding new properties 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; // Fails silently (or throws in strict mode) // delete obj.a; // Fails silently (or throws in strict mode) // obj.a = 10; // Fails silently (or throws in strict mode) console.log(obj); // { a: 1, b: 2 }

Use `requestAnimationFrame` for Smooth Animation

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; // Move 100px in 2 seconds (50px/sec) position = (elapsedTime / 2000) * 100; if (position < 200) { // Keep animating until it reaches 200px box.style.left = position + 'px'; requestAnimationFrame(animate); } else { box.style.left = '200px'; } } // Start the animation // requestAnimationFrame(animate); // Uncomment to run in browser console.log('Use requestAnimationFrame for browser animations.');

Implement `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) { // Handle sparse arrays 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

Implement `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

Implement `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

What are Web Workers?

ویب ورکرز کیا ہیں اور ان کا بنیادی استعمال کیا ہے اس کی وضاحت کریں۔

وضاحت: ویب ورکرز ویب مواد کے لیے پس منظر کے تھریڈز میں اسکرپٹس چلانے کا ایک ذریعہ ہیں۔ بنیادی استعمال کا کیس مین تھریڈ (جو UI اپڈیٹس اور صارف کے تعاملات کو سنبھالتا ہے) سے طویل عرصے سے چلنے والے یا کمپیوٹیشلی طور پر شدید کاموں کو ہٹانا ہے، اس طرح UI کو غیر جوابدہ یا 'منجمد' ہونے سے روکنا ہے۔ ورکرز مین تھریڈ کے ساتھ پیغام رسانی (postMessage اور onmessage) کے ذریعے بات چیت کرتے ہیں۔

// main.js /* if (window.Worker) { const myWorker = new Worker('worker.js'); myWorker.postMessage([5, 3]); // Send data to worker myWorker.onmessage = function(e) { console.log('Result from worker:', e.data); } } else { console.log('Your browser does not support Web Workers.'); } */ // worker.js /* self.onmessage = function(e) { console.log('Message received from main script'); const result = e.data[0] * e.data[1]; console.log('Posting result back to main script'); self.postMessage(result); } */ console.log('Web Workers run scripts in background threads.');

Decode Ways

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' or 'L') console.log(numDecodings('226')); // 3 ('BBF', 'BZ', 'VF') console.log(numDecodings('06')); // 0

Bitwise Addition (without `+`)

+ آپریٹر کا استعمال کیے بغیر دو اعداد کو جمع کرنے کے لیے ایک فنکشن لکھیں۔

وضاحت: بٹ وائز آپریٹرز کا استعمال کریں۔ رقم کا حساب a ^ b (کیری کے بغیر رقم) کے طور پر کیا جا سکتا ہے، اور کیری کا حساب (a & b) << 1 کے طور پر کیا جا سکتا ہے۔ اس عمل کو اس وقت تک دہرائیں جب تک کیری 0 نہ ہو جائے۔

function getSum(a, b) { while (b !== 0) { const carry = (a & b) << 1; // Calculate carry a = a ^ b; // Calculate sum without carry b = carry; // Carry becomes the new 'b' } return a; } console.log(getSum(3, 5)); // 8 console.log(getSum(-2, 3)); // 1

Check for Palindrome (Number)

ایک عدد x دیا گیا ہے، اگر x ایک پیلینڈروم ہے تو true واپس کریں، بصورت دیگر false واپس کریں۔

وضاحت: ایک منفی عدد ایک پیلینڈروم نہیں ہے۔ عدد کو ایک سٹرنگ میں تبدیل کریں اور چیک کریں کہ آیا سٹرنگ ایک پیلینڈروم ہے (آگے اور پیچھے ایک جیسی پڑھتی ہے)۔ متبادل طور پر، عدد کو ریاضیاتی طور پر الٹ کریں اور موازنہ کریں۔

function isPalindromeNumber(x) { if (x < 0) return false; // String approach // return String(x) === String(x).split('').reverse().join(''); // Mathematical approach 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

Factory Pattern

جاوا اسکرپٹ میں فیکٹری ڈیزائن پیٹرن لاگو کریں۔

وضاحت: فیکٹری پیٹرن ایک سپر کلاس میں آبجیکٹس بنانے کے لیے ایک انٹرفیس فراہم کرتا ہے، لیکن سب کلاسز کو تخلیق کیے جانے والے آبجیکٹس کی قسم کو تبدیل کرنے دیتا ہے۔ یہ درست کلاس کی وضاحت کیے بغیر آبجیکٹس بنانے کے لیے مفید ہے۔

class Car { constructor(options) { this.type = 'Car'; this.doors = options.doors || 4; } } class Truck { constructor(options) { this.type = 'Truck'; this.bedSize = options.bedSize || 'long'; } } 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('Unknown vehicle type'); } } } const factory = new VehicleFactory(); const car = factory.createVehicle({ vehicleType: 'car', doors: 2 }); const truck = factory.createVehicle({ vehicleType: 'truck', bedSize: 'short' }); console.log(car); // Car { type: 'Car', doors: 2 } console.log(truck); // Truck { type: 'Truck', bedSize: 'short' }

Explain `Symbol` and a Use Case

جاوا اسکرپٹ میں Symbol کیا ہے اس کی وضاحت کریں اور ایک استعمال کا کیس فراہم کریں، جیسے 'نجی' خصوصیات یا منفرد آبجیکٹ کیز بنانا۔

وضاحت: Symbol ES6 میں متعارف کرایا گیا ایک بنیادی ڈیٹا کی قسم ہے۔ اس کی مثالیں منفرد اور ناقابل تغیر ہیں۔ انہیں اکثر آبجیکٹ کی خصوصیات کے لیے کلیدوں کے طور پر استعمال کیا جاتا ہے تاکہ مختلف لائبریریوں کے درمیان نام کے تصادم سے بچا جا سکے یا چھدم-نجی خصوصیات بنانے کے لیے (اگرچہ حقیقی طور پر نجی نہیں، وہ عام تکرار یا Object.keys کے ذریعے قابل رسائی نہیں ہیں)۔

const _privateName = Symbol('name'); const _privateMethod = Symbol('greet'); class Person { constructor(name) { this[_privateName] = name; } [_privateMethod]() { console.log(`Hello, my name is ${this[_privateName]}`); } introduce() { this[_privateMethod](); } } const p = new Person('Bob'); p.introduce(); // Hello, my name is Bob console.log(Object.keys(p)); // [] - Symbols are not included console.log(p[_privateName]); // Bob (Accessible if you have the Symbol)

Convert `arguments` to a Real Array

آپ arguments آبجیکٹ (جو نان-ایرو فنکشنز میں دستیاب ہے) کو حقیقی جاوا اسکرپٹ ارے میں کیسے تبدیل کر سکتے ہیں؟

وضاحت: arguments آبجیکٹ ایک ارے کی طرح لگتا ہے لیکن یہ ایک ارے نہیں ہے؛ اس میں map، filter وغیرہ جیسے طریقے نہیں ہیں۔ آپ اسے استعمال کر کے تبدیل کر سکتے ہیں:

  1. Array.from(arguments) (ES6)
  2. [...arguments] (ES6 Spread Syntax)
  3. Array.prototype.slice.call(arguments) (پرانا طریقہ)
function sumAll() { // 1. Array.from const args1 = Array.from(arguments); console.log('Using Array.from:', args1.reduce((a, b) => a + b, 0)); // 2. Spread Syntax const args2 = [...arguments]; console.log('Using Spread:', args2.reduce((a, b) => a + b, 0)); // 3. Slice const args3 = Array.prototype.slice.call(arguments); console.log('Using Slice:', args3.reduce((a, b) => a + b, 0)); } sumAll(1, 2, 3, 4); // Using Array.from: 10 // Using Spread: 10 // Using Slice: 10