สมมติว่าเรามีสตริง s เราต้องหาจำนวนสวอปที่อยู่ติดกันขั้นต่ำที่จำเป็นในการทำให้มันเป็นพาลินโดรม หากไม่มีวิธีแก้ปัญหา ให้คืนค่า -1
ดังนั้น หากอินพุตเป็น s ="xxyy" ผลลัพธ์จะเป็น 2 เนื่องจากเราสามารถสลับระหว่าง "x" และ "y" ตรงกลางได้ ดังนั้นสตริงจึงเป็น "xyxy" จากนั้นจึงสลับ "x" สองตัวแรกกับ "x" y" เพื่อให้ได้ "yxxy" และนี่คือ palindrome
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
กำหนดฟังก์ชัน util() นี่จะใช้เวลา s
-
เห็นแล้ว :=แผนที่ใหม่
-
สำหรับแต่ละ i ทำ
-
เห็น[i] :=1 + (เห็น[i] ถ้ามีอยู่ 0)
-
-
odd_count :=0
-
สำหรับแต่ละคู่ของค่าคีย์ที่เห็น ให้ทำ
-
ถ้าค่าเป็นเลขคี่แล้ว
-
odd_count :=odd_count + 1
-
-
ถ้า odd_count เหมือนกับ 2 แล้ว
-
คืนค่าเท็จ
-
-
-
คืนค่า True
-
จากวิธีหลักให้ทำดังต่อไปนี้ -
-
สวอป :=0
-
ถ้า util(s) เป็นจริง แล้ว
-
ซ้าย :=0
-
ขวา :=ขนาด s - 1
-
s :=รายการตัวละครใหม่โดยนำมาจาก s
-
ขณะที่ซ้าย <ขวา ทำ
-
ถ้า s[left] ไม่เหมือนกับ s[right] แล้ว
-
k :=ถูกต้อง
-
ในขณะที่ k> left และ s[k] ไม่เหมือนกับ s[left] ให้ทำ
-
k :=k - 1
-
-
ถ้า k เท่ากับ left แล้ว
-
สวอป :=สวอป + 1
-
s[left], s[left + 1] :=s[left + 1], s[left]
-
-
มิฉะนั้น
-
ในขณะที่ k <ถูกต้อง ทำ
-
สลับ s[k], s[k + 1]
-
k :=k + 1
-
สวอป :=สวอป + 1
-
-
ซ้าย :=ซ้าย + 1
-
ขวา :=ขวา - 1
-
-
-
มิฉะนั้น
-
ซ้าย :=ซ้าย + 1
-
ขวา :=ขวา - 1
-
-
-
คืนสวอป
-
-
กลับ -1
ตัวอย่าง(Python)
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
class Solution: def solve(self, s): def util(s): seen = {} for i in s: seen[i] = seen.get(i, 0) + 1 odd_count = 0 for k, val in seen.items(): if val & 1 == 1: odd_count += 1 if odd_count == 2: return False return True swaps = 0 if util(s): left = 0 right = len(s) - 1 s = list(s) while left < right: if s[left] != s[right]: k = right while k > left and s[k] != s[left]: k -= 1 if k == left: swaps += 1 s[left], s[left + 1] = s[left + 1], s[left] else: while k < right: s[k], s[k + 1] = s[k + 1], s[k] k += 1 swaps += 1 left += 1 right -= 1 else: left += 1 right -= 1 return swaps return -1 ob = Solution() s = "xxyy" print(ob.solve(s))
อินพุต
"xxyy"
ผลลัพธ์
2