কোনও উপাদান অনুসন্ধান করার দক্ষ উপায়


88

সম্প্রতি আমার একটি সাক্ষাত্কার হয়েছিল, যেখানে তারা আমাকে একটি " অনুসন্ধান " প্রশ্ন জিজ্ঞাসা করেছিলেন।
প্রশ্নটি ছিল:

ধরুন এখানে (ধনাত্মক) পূর্ণসংখ্যার একটি অ্যারে রয়েছে যার মধ্যে প্রতিটি উপাদান হয় +1বা -1তার সাথে সংলগ্ন উপাদানগুলির সাথে তুলনা করা হয় ।

উদাহরণ:

এখন অনুসন্ধান করুন 7এবং এর অবস্থানটি ফিরে আসুন ।

আমি এই উত্তরটি দিয়েছি:

অস্থায়ী অ্যারেতে মানগুলি সঞ্চয় করুন, সেগুলি সাজান এবং তারপরে বাইনারি অনুসন্ধান প্রয়োগ করুন।

যদি উপাদানটি পাওয়া যায়, অস্থায়ী অ্যারেতে এর অবস্থানটি ফিরে আসুন।
(যদি সংখ্যাটি দু'বার হয়ে থাকে তবে তার প্রথম উপস্থিতিটি ফিরিয়ে দিন)

তবে তারা এই উত্তরটি নিয়ে সন্তুষ্ট বলে মনে হয় নি।

সঠিক উত্তর কি?


4
যতদূর আমি জানি, অ্যারেতে কোনও উপাদানটির সূচকটি সনাক্ত করার জন্য একটি লিনিয়ার অনুসন্ধান একটি ভাল উপায়। আমি এখনও নিশ্চিত নই যে অন্য কোনও অনুসন্ধান অ্যালগরিদম যা কোনও উপাদানের সূচকটি সনাক্ত করতে দক্ষ।
শন ফ্রান্সিস এন। বালাইস

4
যদি 7 টি কেবল একবার উপস্থিত হওয়ার গ্যারান্টিযুক্ত হয় বা যদি 7টি কীভাবে ফেরত আসে তবে তা আপনি কোলেম্যানের উত্তরের লিনিয়ার অ্যালগরিদমে আরও কিছুটা উন্নত করতে পারেন।
ব্যবহারকারী 1942027

52
যদি আপনার আসল সমাধানটির বাছাই করা দরকার হয় তবে এটি নিখুঁত রৈখিক অনুসন্ধানের চেয়ে খারাপ। আপনি এটি সম্পর্কে সচেতন না বলে মনে হচ্ছে।
কিউবিস্প্ল 42

4
বাছাইয়ের জন্য O (nlogn) প্রয়োজন, এবং একটি বাইনারি অনুসন্ধান হ'ল (লগইন)। আপনার যদি বড় অ্যারে থেকে অনেকগুলি মান সন্ধান করতে হয় তবে আপনার উত্তরটি আরও ভাল হতে পারে তবে আপনি কেবল একবার অনুসন্ধান করতে গেলে ও (এন) অ্যালগোরিদম আরও ভাল হতে পারে।
jingyu9575

23
আমি জানি না কেন অন্য কেউ কেন এটি উল্লেখ করেনি: আপনার পদ্ধতিটি কেবল অদক্ষ ছিল না, এটি ভুল ছিল এবং এটি নিছক অদক্ষতার চেয়ে অনেক খারাপ। প্রয়োজনীয়তা মূল অ্যারেটিতে প্রদত্ত সংখ্যার অবস্থানের জন্য । আপনার পদ্ধতিটি বাছাই করা অ্যারেতে নম্বরটির অবস্থান দেয় । এখন, আপনি বাছাইয়ের আগে সাধারণ অ্যারে টিপলস (সংখ্যা, অরিজিন_পোস) এর অ্যারে রূপান্তর করে মূল অবস্থানটি পুনরুদ্ধার করতে পারেন । তবে আপনি এটি উল্লেখ করেননি, সুতরাং আমি অনুমান করছি আপনি কোনও সাক্ষাত্কারে এটি উল্লেখ করেননি।
টম জাইচ

উত্তর:


126

আপনি প্রায় 1 টিরও বেশি বারের ধাপগুলির সাথে লিনিয়ার সন্ধান করতে পারেন ob গুরুত্বপূর্ণ পর্যবেক্ষণটি হ'ল যদি উদাহরণস্বরূপ array[i] == 4এবং 7 এখনও উপস্থিত না হয় তবে পরবর্তী প্রার্থীর জন্য 7 সূচীতে রয়েছে i+3। কিছুক্ষণের লুপটি ব্যবহার করুন যা বার বার সরাসরি পরবর্তী সম্ভাব্য প্রার্থীর কাছে যায়।

এখানে একটি বাস্তবায়ন, কিছুটা সাধারণীকরণ করা হল। এটি kঅ্যারেতে প্রথম ঘটনাটি আবিষ্কার করে (+ = 1 টি বিধিনিষেধ সাপেক্ষে) বা -1যদি এটি না ঘটে:

আউটপুট:


8
ঠিক আমি কী ভাবছিলাম। এটি হ'ল O(N), তবে এটি করার আরও দ্রুত উপায় আছে বলে আমি মনে করি না।
শাপিরো ইয়াাকভ

4
আপনি আরও বেশি প্রার্থী (উদাহরণস্বরূপ প্রথম এবং শেষ) এর সাথে গড়পড়তাভাবে এটি কিছুটা দ্রুত করতে পারেন, এবং তারপরে লক্ষ্যমাত্রার সবচেয়ে কাছের একটিটির সাথে যেতে পারেন - এটি হ'ল যদি আপনাকে কেবল প্রথম ঘটনাটিই খুঁজে পাওয়া যায় না, তবে একটি ঘটনা আবিষ্কার করতে হয়।
mkadunc

4
@ এমকেডাঙ্ক এটি একটি ভাল ধারণা। আরেকটি পর্যবেক্ষণ হ'ল যদি প্রথম এবং শেষের উপাদানগুলি 7 টি স্ট্র্যাডল হয় তবে সেই বিশেষ ক্ষেত্রে আপনি বাইনারি অনুসন্ধান ব্যবহার করতে পারেন (যদি আপনার কোনটি খুঁজে পাওয়া যায় তা যদি যত্ন না করেন)
জন কোলেম্যান

4
যে ক্ষেত্রে আপনাকে কোনও 7 খুঁজে পাওয়ার দরকার (অগত্যা প্রথমটি নয়), আমি নিম্নলিখিত (ব্যবহারিক) উন্নতির প্রস্তাব করছি। বিভাগগুলির একটি তালিকা তৈরি করুন (দুটি পূর্ণসংখ্যা, 'শুরু' এবং 'শেষ') এবং অ্যারের শুরুতে পরিবর্তে মাঝখানে শুরু করুন। কক্ষের মান অনুযায়ী প্রাসঙ্গিক পরিসর উপেক্ষা করুন এবং আপনার বিভাগগুলির তালিকায় দুটি বামদিকে বিভাগ যুক্ত করুন। এখন তালিকার পরবর্তী আইটেমগুলির জন্য পুনরাবৃত্তি করুন। এটি এখনও 'ও (এন)', তবে প্রতিবার কোনও ঘর পরীক্ষা করার সময় আপনি দ্বিগুণ পরিসীমা উপেক্ষা করবেন।
শাপিরো ইয়াাকভ 4

4
@ শাপিরো ইয়াাকভ: একটি বিভাগের উভয় পক্ষের মানগুলির নীচ থেকে উচ্চতর পর্যন্ত মধ্যবর্তী স্থানের মধ্যে কে ()) অন্তর্ভুক্ত রয়েছে কিনা তা যাচাইয়ের সাথে একত্রিত, এটি তার নিজস্ব একটি উত্তর প্রাপ্য।
গ্রেইবার্ড

35

আপনার পদ্ধতিটি খুব জটিল। আপনার প্রতিটি অ্যারে উপাদান পরীক্ষা করার দরকার নেই। প্রথম মান 4তাই হয়, 7হয় অন্তত 7-4 উপাদান দূরে, এবং আপনাকে সেই এড়িয়ে যেতে পারেন।

প্রোগ্রাম আউটপুট:

সম্পাদনা: @ রাফেল মিডেল এবং @ মার্টিন জ্যাবেলের মন্তব্যের পরে উন্নতি হয়েছে।


4
একটি নিটপিক, if ((skip = 7 - array[i]) < 1) skip = 1;এটি খুব জটিল করে তুলেছে এবং এটি আমার মতে হতাশ করে। আপনি array[i] == 200যদি -193193 টি এড়িয়ে যেতে পারেন এবং প্রতিবার 1 টি এড়িয়ে যান তবে কেন নয় i += abs(7 - array[i])?
ব্যবহারকারী 1942027

4
আপনার skip7 এবং এর মধ্যে সম্পূর্ণ পার্থক্য নির্ধারণ করা উচিত array[i]
মার্টিন জাবেল

@ রাফেল মিডল নো, একটি উপাদান থাকবে না 200, আপনি পাস হয়ে যেতেন 7
আবহাওয়া ভ্যান

4
@ ওয়েদারভেনের আমাদের সেই গ্যারান্টি নেই, কেবল সংলগ্ন মানগুলি একে অপরের থেকে +1/ -1। সুতরাং এটি ঠিক হতে পারে array[0] == 200এবং অন্যরা বেশিরভাগেরই -1
ব্যবহারকারী 1942027

4
@ ওয়েদারভেইনের এই ধারণাটি রয়েছে যে উপাদানটি সর্বদা অ্যারেতে পাওয়া যায় যা সম্ভবত এটি নাও হতে পারে। -1 এই ক্ষেত্রে একটি বৈধ রিটার্ন; যা আপনার কোডটি বেশ খানিকটা বদলে দেয়
ইউজিন

20

প্রচলিত রৈখিক অনুসন্ধানের একটি ভিন্নতা যাওয়ার ভাল উপায় হতে পারে। আমাদের একটি উপাদান চয়ন করুন array[i] = 2। এখন, array[i + 1]হয় হয় 1 বা 3 (বিজোড়) array[i + 2]হবে , (কেবল ধনাত্মক পূর্ণসংখ্যাগুলি) 2 বা 4 (এমনকি সংখ্যা) হবে।

এভাবে চলতে থাকলে, একটি প্যাটার্নটি পর্যবেক্ষণযোগ্য - সমান array[i + 2*n]সংখ্যক ধারণ করবে এবং তাই এই সমস্ত সূচকগুলি উপেক্ষা করা যেতে পারে।

এছাড়াও, আমরা এটি দেখতে পারি

সুতরাং, সূচকটি i + 5পরবর্তী পরীক্ষা করা উচিত এবং কিছুক্ষণের মধ্যে লুপটি সূচীতে প্রাপ্ত মানের উপর নির্ভর করে চেক করার জন্য পরবর্তী সূচকটি নির্ধারণ করতে ব্যবহার করা যেতে পারে i + 5

যদিও এর জটিলতা রয়েছে O(n)(অ্যাসিপটোটিক জটিলতার ক্ষেত্রে লিনিয়ার সময়), সমস্ত সূচকগুলি পরিদর্শন করা না হওয়ায় এটি ব্যবহারিক দিক থেকে স্বাভাবিক রৈখিক অনুসন্ধানের চেয়ে ভাল।

স্পষ্টতই, array[i](আমাদের প্রারম্ভিক বিন্দু) বিজোড় হলে এই সমস্তটি বিপরীত হবে ।


8

জন কোলেম্যান উপস্থাপিত পদ্ধতিটি সমস্ত সম্ভাবনার ক্ষেত্রে সাক্ষাত্কারকারীর প্রত্যাশা ছিল।
আপনি যদি আরও কিছুটা জটিল হতে ইচ্ছুক হন তবে আপনি প্রত্যাশিত এড়িয়ে যাওয়ার দৈর্ঘ্য বাড়িয়ে তুলতে পারেন:
টার্গেট মান কে । প্রথম উপাদনের মান দিয়ে শুরু করুন বনাম অবস্থানে পি এবং পার্থক্য কেভি কল DV পরম মান Av । গতি নেতিবাচক অনুসন্ধানে, অন্যান্য মান হিসাবে শেষ উপাদান একটি উঁকি আছে তোমার দর্শন লগ করা অবস্থানে : যদি ডিভি negative ড নেগেটিভ থাকে, কে উপস্থিত থাকে (কে-এর কোনও ঘটনা যদি গ্রহণযোগ্য হয় তবে আপনি বাইনারি অনুসন্ধানের পদ্ধতি অনুসারে সূচি পরিসরটি এখানে সংক্ষিপ্ত করতে পারেন)। যদি av + au অ্যারের দৈর্ঘ্যের চেয়ে বড় হয় তবে k অনুপস্থিত। (যদি DV × ডু শূন্য, বনাম অথবা U ট সমান।)
( "পরবর্তী") অবস্থান যেখানে ক্রম মাঝখানে ট সঙ্গে বনাম ফিরে আসতে পারে প্রোব: সূচক বৈধতা ছেড়ে যাওয়া হচ্ছে: o = p + 2*av
যদি ডিভি × ড negativeণাত্মক হয় তবে পি + অ্যাভ থেকে ও-অউ-তে কে (পুনরাবৃত্তভাবে?) সন্ধান করুন;
যদি এটি শূন্য হয় তবে আপনি কে তে সমান হন।
ডু DV সমান যদি মাঝখানে মান k করা হয় না, বা অ Av অতিক্রম করে
অথবা আপনি ব্যর্থ পি থেকে ট এটি + + Av হে-অ,
দিন p=o; dv=du; av=au;এবং অনুসন্ধান রাখা।
('60 এর পাঠ্যগুলির পুরো ফ্ল্যাশ-ব্যাকের জন্য, কুরিয়ারের সাথে দেখুন My আমার "1 ম দ্বিতীয় চিন্তা") ব্যবহার করা উচিতo = p + 2*av - 1, যা du সমান ডিভির সমাপ্ত হয় ))


4

ধাপ 1

প্রথম উপাদানটি দিয়ে শুরু করুন এবং এটি check রয়েছে কিনা তা যাচাই করে দেখি cবর্তমান অবস্থানের সূচি of সুতরাং, প্রাথমিকভাবে c = 0,।

ধাপ ২

যদি এটি 7 হয় তবে আপনি সূচকটি খুঁজে পেয়েছেন। এটা c। আপনি যদি অ্যারের শেষ প্রান্তে পৌঁছে গেছেন তবে ব্রেক আউট করুন।

ধাপ 3

যদি এটি না হয়, তবে 7 অবশ্যই ন্যূনতম |array[c]-7|অবস্থানের দূরে থাকতে হবে কারণ আপনি কেবলমাত্র সূচক প্রতি ইউনিট যুক্ত করতে পারেন। অতএব, |array[c]-7|আপনার বর্তমান সূচীতে যুক্ত করুন, সি, এবং চেক করতে আবার স্টেপ 2 এ যান।

সবচেয়ে খারাপ ক্ষেত্রে, যখন বিকল্প 1 এবং -1 হয়, সময় জটিলতা ও (এন) এ পৌঁছতে পারে, তবে গড় কেসগুলি দ্রুত সরবরাহ করা হবে।


জন কোলেম্যানের উত্তর থেকে এটি কীভাবে আলাদা? ( |c-7|যেখানে |array[c]-7|বলা হয়েছে সেখানে পরামর্শ দেওয়া ছাড়াও )
গ্রেইবার্ড

আমি শুধু তার উত্তর দেখেছি। আমি স্বীকার করি যে মূল ধারণাটি একই।
আকেশ্বর ঝা

মূল প্রশ্নটি অনুমান করে না যে অ্যারেটি than এর চেয়ে কম সংখ্যক দিয়ে শুরু হয় So সুতরাং array[c]-7ইতিবাচক বা নেতিবাচক হতে পারে। abs()এগিয়ে যাওয়ার আগে আপনাকে এটি প্রয়োগ করতে হবে।
আরিফেল

হ্যাঁ আপনি ঠিক. এজন্য আমি array[c] - 7মডুলাস অপারেটরটি ব্যবহার করছি |array[c] - 7|,।
আকেশ্বর ঝা

4

এখানে আমি জাভাতে বাস্তবায়ন দিচ্ছি ...


4
কমপক্ষে আধা-আধিকারিক কনভেনশন সহ কোনও ভাষায় Undocumented কোড । "কো" ট্যাগটি উদারভাবে ব্যাখ্যা করা ছাড়াও জন কোলেম্যান এবং আকেশ্বরের জবাব থেকে কীভাবে আলাদা?
গ্রেইবার্ড

3

এখানে একটি বিভাজন এবং বিজয়ী শৈলী সমাধান। আরও অনেক হিসাবরক্ষণের ব্যয়ে, আমরা আরও উপাদান এড়িয়ে যেতে পারি; বাম-থেকে-ডান স্ক্যান না করে মাঝখানে পরীক্ষা করুন এবং উভয় দিক ছেড়ে যান ।


নীল-ফুল্টজ আপনার উত্তর প্রথম ঘটনাটি ফিরে আসবে না তবে অনুসন্ধানের উপাদানটির কোনও এলোমেলো ঘটনা ঘটবে কারণ আপনি মাঝ থেকে শুরু করছেন এবং উভয় দিক থেকে এড়িয়ে যাচ্ছেন।
রাম পাত্র

পুনরাবৃত্তির ক্রমটি স্যুইচ করা পাঠকের কাছে অনুশীলন হিসাবে ছেড়ে যায়।
নিল ফুল্টজ

4
নীড়-ফুল্টজ তারপর দয়া করে আপনার মুদ্রণ () পদ্ধতি কলটিতে বার্তাটি সম্পাদনা করুন।
রাম পাত্র

2

সমস্যার পুনরাবৃত্ত সমাধান সমাধান করতে চেয়েছিলেন an উপভোগ করুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.