diff --git a/3518/Makefile b/3518/Makefile new file mode 100644 index 0000000..82617c4 --- /dev/null +++ b/3518/Makefile @@ -0,0 +1,46 @@ +TARGET_NAME := smallest_palindromic_rearrangement_ii + +PROBLEM_ID := $(notdir $(CURDIR)) + +BUILD_DIR := $(BUILD_ROOT)/$(PROBLEM_ID) + +TARGET := $(BUILD_DIR)/$(TARGET_NAME) + +SOURCES := \ + main.cpp \ + solution.cpp + +OBJECTS := $(SOURCES:%.cpp=$(BUILD_DIR)/%.o) + + +all: build + + +build: $(TARGET) + + +$(TARGET): $(OBJECTS) + @mkdir -p $(BUILD_DIR) + $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@ + + +$(BUILD_DIR)/%.o: %.cpp + @mkdir -p $(BUILD_DIR) + $(CC) $(CFLAGS) -c $< -o $@ + + +run: build + $(TARGET) + + +test: run + + +clean: + rm -rf $(BUILD_DIR) + + +rebuild: clean build + + +.PHONY: all build run test clean rebuild diff --git a/3518/README.md b/3518/README.md new file mode 100644 index 0000000..47c5387 --- /dev/null +++ b/3518/README.md @@ -0,0 +1,74 @@ +# 3518. Smallest Palindromic Rearrangement II + +You are given a string `s` and an integer `k`. + +Return the k-th palindromic of `s`. If there are fewer than `k` distinct palindromic permutations, return an empty string. + +Note: Different rearrangements that yield the same palindromic string are considered identical and are counted once. + +## Example 1 + +**Input:** + +```text +s = "abba", k = 2 +```` + +**Output:** + +```text +"baab" +``` + +**Explanation:** + +The two distinct palindromic rearrangements of `"abba"` are `"abba"` and `"baab"`. + +Lexicographically, `"abba"` comes before `"baab"`. Since `k = 2`, the output is `"baab"`. + +## Example 2 + +**Input:** + +```text +s = "aa", k = 2 +``` + +**Output:** + +```text +"" +``` + +**Explanation:** + +There is only one palindromic rearrangement: `"aa"`. + +The output is an empty string since `k = 2` exceeds the number of possible rearrangements. + +## Example 3 + +**Input:** + +```text +s = "bacab", k = 1 +``` + +**Output:** + +```text +"abcba" +``` + +**Explanation:** + +The two distinct palindromic rearrangements of `"bacab"` are `"abcba"` and `"bacab"`. + +Lexicographically, `"abcba"` comes before `"bacab"`. Since `k = 1`, the output is `"abcba"`. + +## Constraints + +* `1 <= s.length <= 104` +* `s` consists of lowercase English letters. +* `s` is guaranteed to be palindromic. +* `1 <= k <= 106` diff --git a/3518/main.cpp b/3518/main.cpp new file mode 100644 index 0000000..9e1a9ab --- /dev/null +++ b/3518/main.cpp @@ -0,0 +1,59 @@ +#include "solution.cpp" + +#include +#include + +int main(int argc, char *argv[]) { + (void)argc; + (void)argv; + + Solution s; + + // Example 1 + { + std::string result = s.smallestPalindrome("abba", 2); + assert(result == "baab"); + } + + // Example 2 + { + std::string result = s.smallestPalindrome("aa", 2); + assert(result == ""); + } + + // Example 3 + { + std::string result = s.smallestPalindrome("bacab", 1); + assert(result == "abcba"); + } + + // Additional tests + + // Single palindrome + { + std::string result = s.smallestPalindrome("aaa", 1); + assert(result == "aaa"); + } + + // k exceeds number of permutations + { + std::string result = s.smallestPalindrome("aabb", 3); + assert(result == ""); + } + + // Two different characters + { + std::string result = s.smallestPalindrome("aabbcc", 1); + assert(result == "abccba"); + } + + // Already sorted palindrome + { + std::string result = s.smallestPalindrome("abcba", 2); + assert(result == "bacab"); + } + + std::cout << "All tests passed!\n"; + + return 0; +} diff --git a/3518/solution.cpp b/3518/solution.cpp new file mode 100644 index 0000000..3a48c63 --- /dev/null +++ b/3518/solution.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include + +using std::set; +using std::string; +using std::ranges::next_permutation; +using std::ranges::reverse; +using std::ranges::sort; + +class Solution { +public: + string smallestPalindrome(string s, int k) { + + string half = s.substr(0, s.size() / 2); + + sort(half); + + set permutations; + + do { + permutations.insert(half); + } while (next_permutation(half).found); + + if (permutations.size() > std::numeric_limits::max()) { + throw std::overflow_error("Number of permutations exceeds int limit"); + } + int size = static_cast(permutations.size()); + + if (k > size) { + return string(); + } + + auto it = permutations.begin(); + advance(it, k); + + string mirroredHalf = *it; + reverse(mirroredHalf); + + return *it + mirroredHalf; + } +}; diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a7bc957 --- /dev/null +++ b/Makefile @@ -0,0 +1,45 @@ +export ROOT_DIR := $(CURDIR) + +export BUILD_ROOT := $(ROOT_DIR)/build + +export CC = gcc +export LDFLAGS = -lstdc++ + +BUILD_TYPE ?= Release + +ifeq ($(BUILD_TYPE),Debug) + export CFLAGS = -std=c++23 -Wall -Wextra -Werror -Wpedantic -g -O0 +else ifeq ($(BUILD_TYPE),Release) + export CFLAGS = -std=c++23 -Wall -Wextra -Werror -Wpedantic -O2 +else + $(error Unknown BUILD_TYPE: $(BUILD_TYPE)) +endif + + +.PHONY: all clean build run test rebuild + +all: +ifndef PROBLEM_ID + $(error PROBLEM_ID is not set) +endif + $(MAKE) -C $(PROBLEM_ID) + +clean: + rm -rf $(BUILD_ROOT) + +# NOTE: Examples +# make build PROBLEM_ID=3518 BUILD_TYPE=Debug +# make build PROBLEM_ID=3518 +build: + mkdir -p $(BUILD_ROOT)/$(PROBLEM_ID) + $(MAKE) -C $(PROBLEM_ID) build + +run: + $(MAKE) -C $(PROBLEM_ID) run + +test: + $(MAKE) -C $(PROBLEM_ID) test + +rebuild: + $(MAKE) -C $(PROBLEM_ID) clean + $(MAKE) -C $(PROBLEM_ID) build