Linked List เป็นโครงสร้างข้อมูลแบบเชิงเส้นที่องค์ประกอบเชื่อมต่อกันผ่านพอยน์เตอร์ แต่ละโหนด (node) มีส่วนข้อมูล (data) และลิงก์/พอยน์เตอร์ไปยังโหนดถัดไป ข้อมูลอาจจัดเก็บในหน่วยความจำที่ไม่ติดกัน
ได้รับ singly linked list ที่มีส่วนข้อมูลและลิงก์ไปโหนดถัดไป รวมถึงจำนวน K งานคือหาค่าสูงสุด (Max) และต่ำสุด (Min) ใน linked list ที่หารด้วย K ลงตัว เนื่องจากเป็น singly linked list จึงเดินได้เพียงทิศทางเดียว ที่แต่ละโหนดจะตรวจสอบว่าข้อมูลหารด้วย K ลงตัวหรือไม่ หากใช่ และเป็นค่าสูงสุด/ต่ำสุดที่เจอมาจนถึงตอนนั้น ให้อัปเดตค่า MaxD และ MinD
ตัวอย่าง
ตัวอย่างที่ 1
Input: SList: 5→2→10→12→3→20→7, K=5
Output:
Max divisible by K: 20 Min divisible by K: 5
คำอธิบาย: ค่าที่หาร 5 ลงตัวคือ 5, 10, 20 → Min=5, Max=20
ตัวอย่างที่ 2
Input: SList: 12→2→5→18→3→144→7, K=4
Output:
Max divisible by K: 144 Min divisible by K: 12
แนวทางแก้ปัญหา
- สร้างโครงสร้างโหนด (Node) มี
dataและnextpointer - สร้าง Linked List class มี head pointer และเมธอด
addToHead() - สร้าง linked list โดยเรียก
addToHead() - ฟังก์ชัน
findDivisibleMinMax(head, K)รับ head และ K - ในฟังก์ชัน: ตั้ง
maxD = INT_MIN,minD = INT_MAX - เดินผ่านทุกโหนดจาก head จนถึง NULL
- ถ้า
node->data % K == 0ให้อัปเดตmaxDและminD - หลังลูปจบ ถ้า
maxD == INT_MINแสดงว่าไม่มีค่าหารลงตัว
ตัวอย่างโค้ด (สมัยใหม่ ใช้ struct และ smart pointers)
#include <iostream>
#include <climits>
#include <memory>
using namespace std;
struct Node {
int data;
unique_ptr<Node> next;
Node(int val) : data(val), next(nullptr) {}
};
void findDivisibleMinMax(Node* head, int K) {
int maxD = INT_MIN;
int minD = INT_MAX;
bool found = false;
for (Node* curr = head; curr != nullptr; curr = curr->next.get()) {
if (curr->data % K == 0) {
found = true;
if (curr->data > maxD) maxD = curr->data;
if (curr->data < minD) minD = curr->data;
}
}
if (found) {
cout << "Max Element divisible by K: " << maxD << endl;
cout << "Min Element divisible by K: " << minD << endl;
} else {
cout << "No element divisible by " << K << endl;
}
}
int main() {
// สร้าง list: 50→21→32→45→11→23→90→56 (เพิ่มที่ head ดังนั้นลำดับจะกลับ)
auto head = make_unique<Node>(56);
head->next = make_unique<Node>(90);
head->next->next = make_unique<Node>(23);
head->next->next->next = make_unique<Node>(11);
head->next->next->next->next = make_unique<Node>(45);
head->next->next->next->next->next = make_unique<Node>(32);
head->next->next->next->next->next->next = make_unique<Node>(21);
head->next->next->next->next->next->next->next = make_unique<Node>(50);
int K = 5;
findDivisibleMinMax(head.get(), K);
return 0;
}
ผลลัพธ์
Max Element divisible by K: 90 Min Element divisible by K: 45
โค้ดแบบคลาสสิก (ตามต้นฉบับ แต่แก้ไขให้ compile ได้)
#include <iostream>
#include <climits>
using namespace std;
class SLLnode {
public:
int info;
SLLnode* next;
SLLnode(int e, SLLnode* ptr = nullptr) : info(e), next(ptr) {}
};
class SLList {
public:
SLLnode* head;
SLList() : head(nullptr) {}
void addToHead(int el) { head = new SLLnode(el, head); }
~SLList() {
while (head) {
SLLnode* tmp = head;
head = head->next;
delete tmp;
}
}
};
void Divisible(SLLnode* head, int K) {
int minD = INT_MAX;
int maxD = INT_MIN;
bool found = false;
for (SLLnode* curr = head; curr != nullptr; curr = curr->next) {
if (curr->info % K == 0) {
found = true;
if (curr->info < minD) minD = curr->info;
if (curr->info > maxD) maxD = curr->info;
}
}
if (found) {
cout << "Max Element divisible by K: " << maxD << endl;
cout << "Min Element divisible by K: " << minD << endl;
} else {
cout << "No element divisible by " << K << endl;
}
}
int main() {
SLList LIST;
LIST.addToHead(50);
LIST.addToHead(21);
LIST.addToHead(32);
LIST.addToHead(45);
LIST.addToHead(11);
LIST.addToHead(23);
LIST.addToHead(90);
LIST.addToHead(56);
int K = 5;
Divisible(LIST.head, K);
return 0;
}
ความซับซ้อน
- เวลา: O(n) – เดินผ่าน linked list ครั้งเดียว
- พื้นที่: O(1) – ใช้ตัวแปรคงที่