- vừa được xem lúc

Bài toán Tìm vị trí đầu tiên và cuối cùng của phần tử trong mảng đã sắp xếp

0 0 5

Người đăng: Nguyễn Ánh Dung

Theo Viblo Asia

Đề bài

Cho một mảng số nguyên nums được sắp xếp theo thứ tự tăng dần và một số nguyên target, hãy tìm vị trí bắt đầu và kết thúc của target trong mảng.

Nếu target không có trong mảng, trả về [-1, -1].

Ví dụ:

Đầu vào: nums = [5,7,7,8,8,10], target = 8

Đầu ra: [3,4]

Đầu vào: nums = [5,7,7,8,8,10], target = 6

Đầu ra: [-1,-1]

Đầu vào: nums = [], target = 0

Đầu ra: [-1,-1]

Ràng buộc:

0 <= nums.length <= 10^5

-10^9 <= nums[i] <= 10^9

Mảng nums được sắp xếp tăng dần.

-10^9 <= target <= 10^9

Ý tưởng giải

Sử dụng tìm kiếm nhị phân (binary search) để tìm vị trí đầu tiên và cuối cùng của target. Vì mảng đã được sắp xếp, ta có thể:

Tìm vị trí đầu tiên của target bằng cách sử dụng tìm kiếm nhị phân để tìm phần tử đầu tiên bằng hoặc lớn hơn target.

Tìm vị trí cuối cùng của target bằng cách sử dụng tìm kiếm nhị phân để tìm phần tử cuối cùng bằng hoặc nhỏ hơn target.

Nếu cả hai vị trí đều hợp lệ và giá trị tại các vị trí đó là target, trả về [first, last]. Ngược lại, trả về [-1, -1].

Thời gian phức tạp: O(log n), vì tìm kiếm nhị phân có độ phức tạp O(log n) và ta thực hiện nó hai lần.

def searchRange(nums, target): def binarySearch(nums, target, findFirst): left, right = 0, len(nums) - 1 result = -1 while left <= right: mid = (left + right) // 2 if nums[mid] == target: result = mid if findFirst: right = mid - 1 # Tiếp tục tìm bên trái để tìm vị trí đầu tiên else: left = mid + 1 # Tiếp tục tìm bên phải để tìm vị trí cuối cùng elif nums[mid] < target: left = mid + 1 else: right = mid - 1 return result # Tìm vị trí đầu tiên và cuối cùng first = binarySearch(nums, target, True) last = binarySearch(nums, target, False) return [first, last] 

Giải thích code

  1. Hàm binarySearch:

Tham số findFirst quyết định xem ta đang tìm vị trí đầu tiên (True) hay cuối cùng (False).

Nếu tìm thấy target tại mid, lưu lại result nhưng tiếp tục tìm:

Nếu findFirst = True, tiếp tục tìm ở nửa bên trái để tìm vị trí đầu tiên.

Nếu findFirst = False, tiếp tục tìm ở nửa bên phải để tìm vị trí cuối cùng.

Nếu nums[mid] != target, thực hiện tìm kiếm nhị phân thông thường.

  1. Hàm chính searchRange:

Gọi binarySearch hai lần:

Lần đầu với findFirst = True để tìm vị trí đầu tiên.

Lần hai với findFirst = False để tìm vị trí cuối cùng.

Trả về mảng [first, last].

Độ phức tạp

Thời gian: O(log n), do mỗi lần tìm kiếm nhị phân có độ phức tạp O(log n) và ta thực hiện hai lần.

Không gian: O(1), chỉ sử dụng một số biến phụ.

Kết luận

Giải pháp sử dụng tìm kiếm nhị phân là tối ưu cho bài toán này vì tận dụng được tính chất mảng đã sắp xếp, đảm bảo hiệu quả về thời gian. Code trên có thể xử lý tất cả các trường hợp, bao gồm mảng rỗng và target không tồn tại.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Thuật toán quay lui (Backtracking)

Quay lui là một kĩ thuật thiết kế giải thuật dựa trên đệ quy. Ý tưởng của quay lui là tìm lời giải từng bước, mỗi bước chọn một trong số các lựa chọn khả dĩ và đệ quy.

0 0 60

- vừa được xem lúc

Các thuật toán cơ bản trong AI - Phân biệt Best First Search và Uniform Cost Search (UCS)

Nếu bạn từng đọc các thuật toán trong AI (Artificial Intelligence - Trí tuệ nhân tạo), rất có thể bạn từng nghe qua về các thuật toán tìm kiếm cơ bản: UCS (thuộc chiến lược tìm kiếm mù) và Best First Search (thuộc chiến lược tìm kiếm kinh nghiệm). Khác nhau rõ từ khâu phân loại rồi, thế nhưng hai th

0 0 184

- vừa được xem lúc

Sử dụng vector trong lập trình C++ - giải bài toán lập trình muôn thủa

Chào buổi tối mọi người, hôm nay lang thang trên mạng bắt gặp bài toán quen thuộc một thời của quãng đường sinh viên IT. Đấy chính là câu số 1 trong đề thi dưới đây:.

0 0 69

- vừa được xem lúc

MÔ PHỎNG THUẬT TOÁN VƯƠNG HẠO TRONG PROLOG

. 1. Các luật suy diễn trong thuật toán Vương Hạo. Luật 1: Chuyển vế các giả thuyết và kết luận ở dạng phủ định. Ví dụ: p v q, !(r ^ s), !q, p v r -> s, !p <=> p v q, p v r, p -> s, r ^ s, q.

0 0 102

- vừa được xem lúc

A* Search Algorithm

What is A* Search Algorithm. How it works. . Explanation.

0 0 64

- vừa được xem lúc

Python: Jump Search

Search là một từ khóa khá là quen thuộc đối với chúng ta. Hiểu theo đúng nghĩa đen của nó chính là "Tìm kiếm".

0 0 61