সংখ্যার তালিকায় একটি "গর্ত" সন্ধান করুন


14

অচলিত পূর্ণসংখ্যার প্রদত্ত তালিকার অস্তিত্ব নেই এমন প্রথম (ক্ষুদ্রতম) পূর্ণসংখ্যার সন্ধানের দ্রুততম উপায়টি কী (এবং এটি তালিকার ক্ষুদ্রতম মানের চেয়ে বড়)?

আমার আদিম পদ্ধতি তাদের বাছাই করছে এবং তালিকায় পা রাখছে, এর চেয়ে ভাল উপায় আর কি?


6
আমি অসীম অগ্রগতি বাছাই কঠিন হবে ;-) মনে @Jodrell
maple_shaft

3
@ ম্যাপেল_শ্যাফট রাজি হয়েছে, কিছুটা সময় নিতে পারে।
Jodrell

4
নিরবচ্ছিন্ন তালিকার জন্য আপনি কীভাবে প্রথম সংজ্ঞা দেন?
Jodrell

1
আমি ঠিক বুঝতে পেরেছি এটি সম্ভবত স্ট্যাকওভারফ্লোতে অন্তর্ভুক্ত, যেহেতু এটি আসলে কোনও ধারণাগত সমস্যা নয়।
জেসনট্রু ট্রু

2
@ জেসন ট্র্রু এফএকিউ থেকে, If you have a question about… •algorithm and data structure conceptsএটি আইএমএইচও বিষয়।
maple_shaft

উত্তর:


29

ধরুন আপনি যখন "সংখ্যা" বলবেন তখন আপনি "পূর্ণসংখ্যা" বোঝাচ্ছেন, আপনি আকার 2 ^ n এর বিটवेક્ટર ব্যবহার করতে পারেন, যেখানে n উপাদানগুলির সংখ্যা (বলুন যে আপনার পরিসীমাতে 1 এবং 256 এর মধ্যে পূর্ণসংখ্যার অন্তর্ভুক্ত রয়েছে, তবে আপনি একটি 256- ব্যবহার করতে পারেন বিট, বা 32 বাইট, বিটवेেক্টর)। আপনি যখন আপনার পরিসরের n পজিশনে পূর্ণসংখ্যার দিকে এসে পৌঁছান, নবম বিট সেট করুন।

যখন আপনি পূর্ণসংখ্যার সংগ্রহের গণনা সম্পন্ন করেন, আপনি আপনার বিটভেেক্টরের বিটগুলি দিয়ে পুনরাবৃত্তি করেন, যে কোনও বিটের অবস্থান নির্ধারণ করে 0.। সেগুলি এখন আপনার অনুপস্থিত পূর্ণসংখ্য (গুলি) এর অবস্থান n এর সাথে মেলে।

এটি ও (2 * এন), সুতরাং ও (এন) এবং সম্ভবত পুরো তালিকাটি বাছাই করার চেয়ে আরও বেশি মেমরি কার্যকর।


6
ঠিক আছে, সরাসরি তুলনা হিসাবে, যদি আপনার সমস্ত ইতিবাচক স্বাক্ষরযুক্ত 32 বিট ইন্টিজার থাকে তবে 1, আপনি প্রায় অর্ধ গিগাবাইট মেমরির মধ্যে হারিয়ে যাওয়া পূর্ণসংখ্যার সমস্যাটি সমাধান করতে পারেন। আপনি যদি এর পরিবর্তে বাছাই করেন তবে আপনাকে 8 গিগাবাইটের বেশি মেমরি ব্যবহার করতে হবে। এবং বাছাই করা, যেমন এর মতো বিশেষ ক্ষেত্রে বাদে (আপনার তালিকাটি যখন একবার বিটভেেক্টরটি সাজানো থাকে) প্রায় সবসময় এন লগ এন বা আরও খারাপ হয়, সুতরাং ধ্রুবক ব্যয়বহুল জটিলতার তুলনায় লিনিয়ার পদ্ধতির জয় হয়।
জেসনট্রু ট্রু

1
আপনি যদি পরিসীমাটিকে একটি প্রাইরি না জানেন তবে কী হবে?
blrfl

2
আপনার যদি একটি পূর্ণসংখ্যার ডেটা টাইপ থাকে, ব্ল্রফ্ল, আপনার অবশ্যই আরও পরিসীমাটির সীমাবদ্ধতা জানা থাকবে, এমনকি আপনার আরও সংকীর্ণ করার মতো পর্যাপ্ত তথ্য না থাকলেও। যদি আপনি এটি একটি ছোট তালিকা জানেন তবে সঠিক আকারটি না জানেন তবে বাছাই করা সহজ সমাধান হতে পারে।
জেসনট্রু

1
অথবা ক্ষুদ্রতম এবং বৃহত্তম উপাদানটি খুঁজে পেতে প্রথমে তালিকার মাধ্যমে আরও একটি লুপ করুন। তারপরে আপনি বেসিক অফসেট হিসাবে ক্ষুদ্রতম মান সহ সঠিক আকারের একটি অ্যারের বরাদ্দ করতে পারেন। এখনও).
সুরক্ষিত করুন

1
@ জেপ্যাট্রিক: হোম ওয়ার্ক নয়, ব্যবসায় নয়, আমি সিএস বছর আগে স্নাতক হয়েছি :)।
ফ্যাবিয়ান জাইন্ডল

4

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

আমি কীভাবে এই সমস্যার কাছে যাব তা এখানে:

  1. তালিকার ক্ষুদ্রতম উপাদানগুলিতে ফোকাস করে একটি হিপ সাজান ব্যবহার করুন ।
  2. প্রতিটি অদলবদলের পরে, আপনার কোনও ফাঁক আছে কিনা তা দেখুন।
  3. আপনি যদি কোনও ফাঁক খুঁজে পান তবে return: আপনি নিজের উত্তর খুঁজে পেয়েছেন।
  4. আপনি যদি কোনও ফাঁক খুঁজে না পান তবে অদলবদল চালিয়ে যান।

এখানে একটি ব্যাপার এক গাদা সাজানোর কল্পনা


একটি প্রশ্ন, আপনি কীভাবে তালিকার "ক্ষুদ্রতম" উপাদানগুলি সনাক্ত করতে পারেন?
জোডরেল

4

কেবল রহস্যময় এবং "চালাক" হতে গেলে অ্যারের বিশেষ ক্ষেত্রে কেবল একটি "গর্ত" রয়েছে, আপনি একটি এক্সওআর ভিত্তিক সমাধান চেষ্টা করতে পারেন:

  • আপনার অ্যারের ব্যাপ্তি নির্ধারণ করুন; এটি অ্যারের প্রথম উপাদানটির জন্য "সর্বাধিক" এবং "মিনিট" পরিবর্তনশীল সেট করে সম্পন্ন হয় এবং তার পরে প্রতিটি উপাদানগুলির জন্য, যদি সেই উপাদানটি নূন্যতমের চেয়ে কম হয় বা সর্বাধিকের চেয়ে বড় হয়, তবে মিনিট বা সর্বোচ্চটি সেট করুন নতুন মান
  • যদি সেটটির কার্ডিনালিটির চেয়ে পরিসীমাটি একরকম কম হয় তবে কেবলমাত্র একটি "গর্ত" রয়েছে যাতে আপনি এক্সওআর ব্যবহার করতে পারেন।
  • একটি পূর্ণসংখ্যা পরিবর্তনশীল এক্স থেকে শূন্যের সূচনা করুন।
  • সর্বনিম্ন থেকে সর্বোচ্চ পর্যন্ত প্রতিটি পূর্ণসংখ্যার জন্য, এক্সওর যে এক্স এর সাথে মান দেয় এবং এক্সকে ফলাফল সংরক্ষণ করে
  • এক্সের সাথে অ্যারেতে প্রতিটি পূর্ণসংখ্যার এক্সওর করুন, প্রতিটি ধারাবাহিক ফলাফলকে পূর্বের মতো এক্সে সংরক্ষণ করুন।
  • আপনার হয়ে গেলে এক্স আপনার "গর্ত" এর মান হবে।

এটি বিটভেেক্টর সমাধানের মতো প্রায় 2N সময়ে চলবে তবে যে কোনও এন> আকারের (ইনট) এর জন্য কম মেমরির স্থান প্রয়োজন। তবে অ্যারেটিতে যদি একাধিক "গর্ত" থাকে তবে এক্স সমস্ত গর্তের এক্সওআর "যোগফল" হবে, যা প্রকৃত গর্তের মানগুলিতে পৃথক হওয়া কঠিন বা অসম্ভব। সেক্ষেত্রে আপনি অন্য কিছু পদ্ধতিতে ফিরে যান যেমন "পিভট" বা "বিটভেেক্টর" অন্যান্য উত্তরগুলির পদ্ধতির।

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


এটি হাস্যকরভাবে চালাক এবং দুর্দান্ত! এখন আপনি পরিবর্তনশীল সংখ্যক গর্ত দিয়ে এটি করার কোনও উপায় নিয়ে আসতে পারেন? :-D

2

আপনার মুখোমুখি হবে সংখ্যার পরিসীমা কত? যদি এই ব্যাপ্তিটি খুব বড় না হয় তবে আপনি দুটি স্ক্যান (লিনিয়ার টাইম ও (এন)) দিয়ে সমাধান করতে পারেন আপনার সংখ্যা হিসাবে যতগুলি উপাদান রয়েছে তার সাথে অ্যারে ব্যবহার করে, সময়ের জন্য ট্রেডিং স্পেস। আপনি আরও একটি স্ক্যান করে গতিশীলভাবে পরিসীমাটি খুঁজে পেতে পারেন। স্থান হ্রাস করতে, আপনি প্রতিটি সংখ্যাতে 1 বিট বরাদ্দ করতে পারেন, আপনাকে প্রতি বাইটে 8 নম্বর মূল্য সঞ্চয় করে।

আপনার অন্যান্য বিকল্প যা প্রারম্ভিক পরিস্থিতিগুলির জন্য ভাল হতে পারে এবং মেমরি অনুলিপি করার পরিবর্তে উত্তম হতে পারে তা হল স্ক্যানিং পাসের মধ্যে পাওয়া নূন্যতমটি সর্বনিম্ন মিনিটের সন্ধানের চেয়ে 1 টি না হলে তাড়াতাড়ি প্রস্থান করতে সিলেক্ট সাজ্ট পরিবর্তন করা।


1

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


1
আপনি কি বলছেন যে তালিকার সন্ধান করা বাছাই করা একই সময়ের জটিলতা?
maple_shaft

@ ম্যাপেল_শ্যাফ্ট: না, আমি বলছি র্যান্ডম ডেটা থেকে বাইনারি ট্রি তৈরি করা এবং তারপরে এটিকে বাম থেকে ডান দিকে অনুসরণ করা বাছাই করার সমতুল্য এবং তারপরে ছোট থেকে বড় ট্র্যাভারিংয়ের সমান।
পিলমুনচার

1

এখানে বেশিরভাগ ধারণা কেবল বাছাই করা ছাড়া আর কিছু নয় are বিটवेেক্টর সংস্করণটি সরল বালতিসোর্ট। গাদা সাজানোর কথাও উল্লেখ করা হয়েছিল। এটি মূলত সঠিক বাছাই করা অ্যালগরিদমকে বেছে নেওয়ার জন্য সিদ্ধ হয় যা সময় / স্থানের প্রয়োজনীয়তার উপর এবং উপাদানগুলির পরিসর এবং সংখ্যার উপরও নির্ভর করে।

আমার মতে, একটি গাদা কাঠামো ব্যবহার করা সম্ভবত সর্বাধিক সাধারণ সমাধান (একটি গাদা মূলত আপনাকে সম্পূর্ণ বিন্যাস ছাড়াই দক্ষতার সাথে ক্ষুদ্রতম উপাদান দেয়) gives

আপনি প্রথমে ক্ষুদ্রতম সংখ্যাগুলি খুঁজে পাওয়া এমন পদ্ধতির বিশ্লেষণও করতে পারেন এবং তারপরে প্রতিটি পূর্ণসংখ্যার চেয়ে বড় স্ক্যান করতে পারেন। অথবা আপনি 5 টি ক্ষুদ্রতম সংখ্যাটি খুঁজে পাচ্ছেন আশা করে একটি ফাঁক থাকবে।

এই সমস্ত অ্যালগরিদমের ইনপুট বৈশিষ্ট্য এবং প্রোগ্রামের প্রয়োজনীয়তার উপর নির্ভর করে তাদের শক্তি রয়েছে।


0

একটি সমাধান যা অতিরিক্ত সঞ্চয়স্থান ব্যবহার করে না বা পূর্ণসংখ্যার প্রস্থ (32 বিট) ধরে না।

  1. একটি লিনিয়ার পাসে সর্বাধিক সংখ্যাটি সন্ধান করুন। এটিকে "মিনিট" কল করতে দিন। ও (এন) সময়ের জটিলতা।

  2. একটি এলোমেলো পিভট উপাদান বেছে নিন এবং একটি কুইকোর্ট শৈলী বিভাজন করুন।

  3. যদি পাইভটটি = ("পিভট" - "মিনিট") পজিশনে সমাপ্ত হয়, তবে পার্টিশনের ডানদিকে পুনরাবৃত্তি করুন, অন্যথায় পার্টিশনের বাম দিকে পুনরাবৃত্তি করুন। এখানে ধারণাটি হ'ল যদি প্রথম থেকে কোনও গর্ত না থাকে তবে পাইভটটি "" পিভট "-" মিনিট ") তম অবস্থানে থাকবে, সুতরাং প্রথম গর্তটি পার্টিশনের ডানদিকে এবং তার বিপরীতে থাকা উচিত।

  4. বেস কেস 1 টি উপাদানের একটি অ্যারে এবং গর্তটি এই উপাদান এবং পরবর্তীটির মধ্যে থাকে।

প্রত্যাশিত মোট চলমান সময়ের জটিলতা হ'ল ও (এন) (ধ্রুবকগুলির সাথে 8 * এন) এবং সবচেয়ে খারাপ পরিস্থিতি হ'ল ও (এন ^ 2)। অনুরূপ সমস্যার জন্য সময় জটিলতার বিশ্লেষণ এখানে পাওয়া যাবে


0

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

এই পদ্ধতির পিছনে ধারণাটি কুইকোর্টের মতো, আমরা এটির চারপাশে একটি পাইভট এবং বিভাজন খুঁজে পাই, তারপরে একটি গর্ত দিয়ে পাশ (গুলি) এ পুনরাবৃত্তি করি। কোন দিকটির গর্ত রয়েছে তা দেখতে, আমরা সর্বনিম্ন এবং সর্বাধিক সংখ্যা খুঁজে পাই এবং সেগুলির সাথে পাইভট এবং মানগুলির সংখ্যার সাথে তুলনা করি। পাইভটটি 17 এবং সর্বনিম্ন সংখ্যা 11 বলুন যদি কোনও গর্ত না থাকে তবে 6 টি সংখ্যা (11, 12, 13, 14, 15, 16, 17) হওয়া উচিত। যদি 5 টি থাকে তবে আমরা জানি যে সেই পাশের একটি গর্ত আছে এবং এটি সন্ধানের জন্য আমরা কেবল সেই দিকেই পুনরাবৃত্তি করতে পারি। আমি এর থেকে আরও পরিষ্কারভাবে ব্যাখ্যা করতে আমার সমস্যা হচ্ছে, সুতরাং আসুন একটি উদাহরণ নেওয়া যাক।

15 21 10 13 18 16 22 23 24 20 17 11 25 12 14

পিভট:

10 13 11 12 14 |15| 21 18 16 22 23 24 20 17 25

15 হলেন পাইভট, পাইপ দ্বারা নির্দেশিত ( ||)। পিভটের বাম দিকে 5 টি সংখ্যা রয়েছে, কারণ সেখানে (15 - 10) এবং ডানদিকে 9 হওয়া উচিত, যেখানে 10 (25 - 15) হওয়া উচিত। সুতরাং আমরা ডানদিকে পুনরাবৃত্তি করি; আমরা নোট করব যে গর্তটি সংলগ্ন হলে পূর্বের গণ্ডিটি 15 ছিল (16)।

[15] 18 16 17 20 |21| 22 23 24 25

এখন বাম দিকে 4 সংখ্যা রয়েছে তবে 5 (21 - 16) হওয়া উচিত। সুতরাং আমরা সেখানে পুনরাবৃত্তি করি এবং আবার আমরা পূর্বের আবদ্ধ (বন্ধনীগুলিতে) নোট করব।

[15] 16 17 |18| 20 [21]

বাম দিকে সঠিক 2 সংখ্যা রয়েছে (18 - 16), তবে ডানদিকে 2 (20 - 18) এর পরিবর্তে 1 টি রয়েছে। আমাদের শেষের অবস্থার উপর নির্ভর করে আমরা 1 নম্বরটিকে দুটি পক্ষের (18, 20) সাথে তুলনা করতে পারি এবং দেখতে পাচ্ছি যে 19 টি অনুপস্থিত বা আরও একবার পুনরাবৃত্তি করছে:

[18] |20| [21]

বাম পাশের একটি শূন্যের আকার রয়েছে, পিভট (20) এবং পূর্বের আবদ্ধ (18) এর মধ্যে ফাঁক রয়েছে, তাই 19 গর্ত।

*: যদি ডুপ্লিকেট থাকে তবে আপনি সম্ভবত সামগ্রিক পদ্ধতি ও (এন) রেখে ও (এন) সময়ে এগুলি অপসারণ করতে একটি হ্যাশ সেট ব্যবহার করতে পারেন তবে এটি অন্য কোনও পদ্ধতি ব্যবহারের চেয়ে বেশি সময় নিতে পারে


1
আমি বিশ্বাস করি না যে ওপি কেবল একটি গর্ত থাকার বিষয়ে কিছু বলেছিল। ইনপুটটি হ'ল সংখ্যার তালিকাভুক্ত তালিকা - এগুলি যে কোনও কিছু হতে পারে। আপনার বিবরণ থেকে এটি পরিষ্কার নয় যে আপনি কীভাবে নির্ধারণ করবেন যে সেখানে "সংখ্যাটি কত" হওয়া উচিত।
কালেব

@ কালেব এখানে কতগুলি ছিদ্র রয়েছে তা বিবেচনাধীন নয়, কেবল কোনও সদৃশ (যা হে (এন) এ একটি হ্যাশ সেট দিয়ে সরানো যেতে পারে, যদিও বাস্তবে অন্যান্য পদ্ধতির তুলনায় বেশি ওভারহেড থাকতে পারে)। আমি বর্ণনাটি উন্নত করার চেষ্টা করেছি, এটি আরও ভাল কিনা তা দেখুন।
কেভিন

এটি লিনিয়ার নয়, আইএমও। এটি আরও বেশি (লগএন) ^ 2 এর মতো। প্রতিটি পদক্ষেপে, আপনি যে সংগ্রহটি যত্নশীল সেটির সাবসেটটি পিভট করেছেন (পূর্বের সাবারির অর্ধেক যা আপনি "প্রথম" গর্ত "বলে চিহ্নিত করেছেন), তারপরে যদি কোনও" ছিদ্র "থাকে তবে বাম দিকের দুটি অংশে পুনরাবৃত্তি করুন, বা ডান দিকটি যদি বাম দিকটি না করে। (লগএন) ar 2 লিনিয়ারের চেয়ে আরও ভাল; যদি এন দশগুণ বৃদ্ধি পায় আপনি কেবল 2 (লগ (এন) -1) + আরও 1 পদক্ষেপের ক্রম গ্রহণ করেন।
কিথস

@ কিথ - দুর্ভাগ্যক্রমে, আপনি প্রতিটি স্তরের সমস্ত সংখ্যাগুলি দেখতে তাদের লক্ষ্য করতে হবে, সুতরাং এটি n + n / 2 + n / 4 + ... = 2n (প্রযুক্তিগতভাবে, 2 (এনএম)) তুলনা করবে ।
কেভিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.