diff --git a/dynamic_programming/arithmetic_slices.py b/dynamic_programming/arithmetic_slices.py new file mode 100644 index 000000000000..a186f14e3393 --- /dev/null +++ b/dynamic_programming/arithmetic_slices.py @@ -0,0 +1,80 @@ +""" +An integer array is called arithmetic if it +consists of at least three elements and if +the difference between any two consecutive +elements is the same. + +Given an integer array nums, +return the number of +arithmetic subarrays of nums. + +A subarray is a contiguous +subsequence of the array. + +""" + + +class ArithmeticSlices: + def numberofarithmeticslices(self, nums): + """ + This defines a class and a function. + `nums` is input list of integers. + """ + n = len(nums) + + """ + We store the length of the + array nums in variable n + """ + if n < 3: + return 0 + + total = 0 + curr = 0 + + """ + An *arithmetic slice* must have **at least 3 numbers**. + + So, if the array has fewer than 3 elements, + no arithmetic slices are possible — immediately return `0`. + """ + + for i in range(2, n): + if nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]: + curr += 1 + total += curr + else: + curr = 0 + + """ + We start iterating from index `2` + because we need **three elements** + (`nums[i-2], nums[i-1], nums[i]`) + to check if they form an arithmetic pattern. + +<<<<<<< HEAD + So at each step, + we are looking at a triplet ending at index `i`. +======= + So at each step, + we’re looking at a triplet ending at index `i`. +>>>>>>> ca34f0a649ef94c8b778a4babe040fcaa143a56e + """ + + return total + + +""" +test_cases = [ + # Basic cases + ([1, 2, 3, 4], 3), # [1,2,3], [2,3,4], [1,2,3,4] + ([1, 3, 5, 7, 9], 6), # all diffs = 2; + total slices = 6 + + # Edge cases + ([1, 2], 0), # less than 3 elements → 0 + ([1, 1, 1], 1), # [1,1,1] itself is arithmetic + ([1], 0), # single element + ([], 0), # empty array + ] +""" diff --git a/dynamic_programming/beautiful_arrangement.py b/dynamic_programming/beautiful_arrangement.py new file mode 100644 index 000000000000..7302d267eeea --- /dev/null +++ b/dynamic_programming/beautiful_arrangement.py @@ -0,0 +1,64 @@ +""" +Suppose you have n integers labeled 1 through n. +A permutation of those n integers +perm (1-indexed) is considered a +"beautiful arrangement" if for every i (1 <= i <= n), +either of the following is true: + +-> perm[i] is divisible by i. +-> i is divisible by perm[i]. +Given an integer n, return the number of the +"beautiful arrangements" that you can construct. + +""" +# Solution using Backtracking + + +class BeautifulArrange: + # function call; n is the size of the permutation (numbers 1..n) + def countarrangement(self, n: int) -> int: + self.count = 0 + """ + We initialize a counter to record how + many valid arrangements we find. + Using self.count lets the nested + function modify it without nonlocal. + """ + + used = [False] * (n + 1) + """ + A boolean list to mark which numbers have + already been placed in the permutation. + """ + + def backtrack(pos): + """ + Define the recursive backtracking function. + pos is the current position in the + permutation we are filling (1-indexed). + We try to assign a number to position pos. + """ + if pos > n: + self.count += 1 + # We found a complete valid arrangement, so increment the total count. + return + for num in range( + 1, n + 1 + ): # Try every candidate number num for the current position pos. + """ + Two checks in one: + 1. not used[num] — the number num has + not been placed yet (we can use it). + 2. (num % pos == 0 or pos % num == 0) — + the beautiful-arrangement condition: + either num divides pos or pos divides num. + If both are true, num is a valid choice for pos. + + """ + if not used[num] and (num % pos == 0 or pos % num == 0): + used[num] = True + backtrack(pos + 1) + used[num] = False + + backtrack(1) + return self.count