Array Problem
โจทย์ที่ 3: Single Number
โจทย์ https://leetcode.com/problems/single-number/description
อธิบายโจทย์แบบสั้นๆ มี Array nums มาให้ โดยตัวเลขใน array นี้จะซ้ำสองตัวเสมอ แต่จะมี “เพียงตัวเดียว” ที่จะไม่ซ้ำกัน จงนำตัวเลขนั้นออกมา
จากข้อมูลที่โจทย์ให้มา
Example 1:
Input: nums = [2,2,1]
Output: 1
Example 2:
Input: nums = [4,1,2,1,2]
Output: 4
Example 3:
Input: nums = [1]
Output: 1
เช่น จาก Testcase นี้
- Example 1 input คือ [2,2,1] เราจะเจอว่า 1 คือตัวเลขตัวเดียวที่ไม่ซ้ำกัน ดังนั้น output = 1 เป็นคำตอบออกมา
- Example 2 input คือ [4,1,2,1,2] เราจะเจอว่า 4 คือตัวเลขตัวเดียวที่ไม่ซ้ำกัน ดังนั้น output = 4 เป็นคำตอบออกมา
จากตัวอย่างนี้ Idea ที่เป็นไปได้แน่นอนคือ
- ต้อง Loop ภายใน Array เพื่อหาที่ไม่ซ้ำออกมา
- จาก LeetCode ใช้ Vector เช่นเดิม เพื่อรองรับ Array ที่มีหลายๆขนาดได้
Solution
class Solution {
public:
int singleNumber(vector<int> &nums) {
for (int i = 0; i < nums.size(); ++i) {
bool isSingle = true;
for (int j = 0; j < nums.size(); ++j) {
if (i != j && nums[i] == nums[j]) {
isSingle = false;
break;
}
}
if (isSingle) {
return nums[i];
}
}
// This line should theoretically never be reached if the input meets the
// problem's conditions
return -1; // Placeholder return value
}
};
Core idea คือ
- ใช้ singleNumber วน loop ซ้ำสองชั้นเพื่อเปรียบเทียบแต่ละ element ใน vector
nums
- function จะ return ตัวเลขที่ปรากฏเพียงครั้งเดียว หรือ return -1 ถ้าไม่มีตัวเลขที่ปรากฏเพียงครั้งเดียว การทำงานคือ
- loop ผ่านแต่ละ element ใน vector
nums
โดยใช้ตัวแปร i - ภายใน for แต่ละรอบ วนซ้ำ อีกครั้ง ผ่านแต่ละ element ใน vector
nums
โดยใช้ตัวแปรวนซ้ำ j - เปรียบเทียบ
nums[i]
กับnums[j]
- ถ้า i ไม่เท่ากับ j (ไม่ใช่ตำแหน่งเดียวกัน) และ
nums[i]
เท่ากับnums[j]
- ตั้งค่า
isSingle
เป็น false (แปลว่ามีตัวเลขซ้ำกันเกิดขึ้น)
- ถ้า i ไม่เท่ากับ j (ไม่ใช่ตำแหน่งเดียวกัน) และ
- หลังจากออกจาก for ที่วนครบทุกตัว (ภายใน)
- ถ้า
isSingle
ยังเป็น true = returnnums[i]
ออกไปได้เลย (แปลว่าไม่มีตำเลขซ้ำเกิดขึ้น)
- ถ้า
** จริงๆข้อนี้มี Solution ที่ดีกว่านี้ และใช้เพียง 1 loop อยู่
โจทย์ที่ 4: Search Insert Position
โจทย์ https://leetcode.com/problems/search-insert-position/description
อธิบายโจทย์แบบสั้นๆ มี Array ตัวเลขมาให้เรียงแล้วเรียบร้อย ให้หาตำแหน่งของตัวเลข target ที่ระบุมาว่าอยู่ index ที่เท่าไหร่ โดย มีกฎอยู่ว่า ถ้าหาตัวเลขนั้นไม่เจอ ให้ “บอก index ที่ต้องแทรกของตัวเลขนั้นออกมาแทน”
จากข้อมูลที่โจท ย์ให้มา
Example 1:
Input: nums = [1,3,5,6], target = 5
Output: 2
Example 2:
Input: nums = [1,3,5,6], target = 2
Output: 1
Example 3:
Input: nums = [1,3,5,6], target = 7
Output: 4
เช่น จาก Testcase นี้
- Example 1 input คือ [1,3,5,6] และต้องการหาเลข 5 ซึ่งก็ชัดเจนตำแหน่งอยู่ index ที่ 2 Output ก็จะคืนเป็น index 2 ออกมา
- Example 2 input คือ [1,3,5,6] และต้องการหาเลข 2 แต่เคสนี้ก็ชัดเจนเช่นกันว่าไม่มี และ index ที่มันจะต้องแทรกคือตำแหน่งระหว่าง 1 และ 3 ซึ่งก็คือ index 1 ที่จะทำให้ออกมาเป็น Array [1,2,3,5,6] ที่เรียงกันถูกต้องเหมือนเดิมออกมาได้
จากตัวอย่างนี้ Idea ที่เป็นไปได้แน่นอนคือ
- ต้อง Loop ภายใน Array เพื่อหาตัวเลข
- และถ้าไม่เจอตัวเลขต้องทำอะไรสักอย่างเพื่อระบุ Index ออกมาได้
คำใบ้ ไม่ต้องสร้าง Array ใหม่ออกมาจริงๆ
Solution
class Solution {
public:
int searchInsert(vector<int> &nums, int target) {
for (int i = 0; i < nums.size(); i++) {
// เช็ค target ว่าเจอ (target == nums[i]) สามารถคืน index ไปได้เลย
// หรือ ถ้า element ตัวที่กำลังวน loop อยู่มีค่ามากกว่า (nums[i] > target) แปลว่านี่คือตำแหน่งที่สามารถแทรกเข้าไปได้
// ดังนั้น เมื่อรวม logic กันก็จะสามารถใช้เป็น >= ได้
if (nums[i] >= target) {
return i;
}
}
// ถ้าเกิดไม่เจอเลย แปลว่าตัวเลข target ใหญ่กว่าทุกตัวใน Array ให้คืนขนาดของ Array
// ตำแหน่งสุดท้ายออกไปแทน
return nums.size();
}
};