├── .gitignore
├── Algorithms
├── Dynamic-Programming
│ ├── canSum.py
│ └── fibonacci.py
└── Loops
│ └── nestedLoops.py
├── coding-interview
├── amazon
│ └── process-dates.test.js
└── meta
│ └── rotational-ciphers.test.js
├── coverage
├── clover.xml
├── coverage-final.json
├── lcov-report
│ ├── base.css
│ ├── block-navigation.js
│ ├── favicon.png
│ ├── index.html
│ ├── prettify.css
│ ├── prettify.js
│ ├── sort-arrow-sprite.png
│ └── sorter.js
└── lcov.info
├── data-structures
├── binary-search-trees
│ ├── BST-counting-occurrence.test.js
│ ├── BST-insertStrings.test.js
│ ├── BSTremoveNode.test.js
│ ├── BSTsearches.test.js
│ ├── insertBST.test.js
│ ├── python
│ │ └── insertIntoTree.py
│ └── traverseBST.test.js
├── binary-trees
│ ├── javascript
│ │ └── binaryTree.test.js
│ └── python
│ │ ├── 1-binaryTree.py
│ │ ├── 2-traversals.py
│ │ └── binarySearchTree.py
├── graphs
│ ├── connectCompCount.py
│ ├── hasPath.py
│ ├── island_count.py
│ ├── largestComp.py
│ ├── minIslands.py
│ ├── shortest_path.py
│ ├── traversals_bfs.py
│ ├── traversals_dfs.py
│ └── undirected_path.py
├── heaps
│ ├── Heap.test.js
│ └── MinHeap.test.js
├── linked-list
│ ├── linkedList.py
│ └── singlyLinkedList.test.js
├── queue
│ └── ImplementAQueueDs.test.js
└── readme.md
├── hackerRank
├── Arrays
│ ├── readme.md
│ └── reverseIntArr.test.js
├── linkedList
│ ├── compareTwoList.js
│ ├── compareTwoList.test.js
│ ├── cycleDetection.js
│ ├── cycleDetection.test.js
│ ├── deleteNodeAtPos.js
│ ├── deleteNodeAtPos.test.js
│ ├── getNodeValue.js
│ ├── getNodeValue.test.js
│ ├── insertAtHead.js
│ ├── insertAtHead.test.js
│ ├── insertAtTail.js
│ ├── insertAtTail.test.js
│ ├── insertIntoDoublyLinkedList.js
│ ├── insertNodeAtAGivenPos.js
│ ├── insertNodeAtAGivenPos.test.js
│ ├── mergePoint.js
│ ├── mergeSortedList.js
│ ├── printInReverse.js
│ ├── printInReverse.test.js
│ ├── printLinkedList.js
│ ├── printLinkedList.test.js
│ ├── readme.md
│ ├── reverseDoublyLinkedList.js
│ └── reverseDoublyLinkedList.test.js
└── readme.md
├── index.js
├── leetcode
├── javascript
│ ├── easy
│ │ ├── BST-testcase.test.js
│ │ ├── arithmetic-progression.test.js
│ │ ├── balancedBinaryTree.test.js
│ │ ├── bestTimeToBuyAndSellStock.test.js
│ │ ├── binarySearch.test.js
│ │ ├── contains-duplicates.test.js
│ │ ├── contains-dupsII.test.js
│ │ ├── diameterBinaryTree.test.js
│ │ ├── firstPalindrome.test.js
│ │ ├── group-anagrams.test.js
│ │ ├── happyNum.test.js
│ │ ├── implementStackUsingQueues.test.js
│ │ ├── invertBST.test.js
│ │ ├── isPalindrome.test.js
│ │ ├── isValid.test.js
│ │ ├── max-subarray.test.js
│ │ ├── maxDiff.test.js
│ │ ├── maximumDepthBST.test.js
│ │ ├── mergeLinkedList.test.js
│ │ ├── minStack.test.js
│ │ ├── palindromeLList.test.js
│ │ ├── palindromeNum.test.js
│ │ ├── product-sign.test.js
│ │ ├── removeDupsFromSortedArr.test.js
│ │ ├── removeElement.test.js
│ │ ├── reverseLinkedList.test.js
│ │ ├── romanToInt.test.js
│ │ ├── sameTree.test.js
│ │ ├── sortArrayByParity.test.js
│ │ ├── string-swap.test.js
│ │ └── twoSum.test.js
│ ├── hard
│ │ └── medianOfSortedArr.test.js
│ └── medium
│ │ ├── 3Sum.test.js
│ │ ├── addTwoNumbers.test.js
│ │ ├── contains-dupsIII.test.js
│ │ ├── designWordDS.test.js
│ │ ├── getTargetCopy.test.js
│ │ ├── implementTrie.test.js
│ │ ├── longestPalindrome.test.js
│ │ ├── longestSubstring.test.js
│ │ ├── maxOperations.test.js
│ │ ├── maxProfitII.test.js
│ │ ├── removeDupsInString.test.js
│ │ ├── reverseInteger.test.js
│ │ ├── subsets.test.js
│ │ ├── twoSum-ii.test.js
│ │ └── unsortedSubArray.test.js
├── python
│ ├── BFS
│ │ └── jumpGameIII.py
│ ├── bit-manipulation
│ │ ├── countingBits.py
│ │ ├── hammingWeight.py
│ │ ├── reverseBits.py
│ │ ├── reverseInt.py
│ │ └── sumTwoInt.py
│ ├── easy
│ │ ├── climbStairs.py
│ │ ├── findJudge.py
│ │ ├── isAnagram.py
│ │ ├── llistIntersection.py
│ │ ├── maxProfit.py
│ │ ├── mergeSortedArr.py
│ │ ├── minCostClimbingStairs.py
│ │ ├── removePalindromeSub.py
│ │ ├── runningSum.py
│ │ ├── test_kthLargest.py
│ │ ├── test_lastStoneWeight.py
│ │ ├── test_twoSum.py
│ │ ├── transposeMatrix.py
│ │ ├── twoSum.py
│ │ ├── validPalindrome.py
│ │ ├── validParentheses.py
│ │ └── validPath.py
│ ├── greedy
│ │ ├── gasStation.py
│ │ ├── handsOfStraights.py
│ │ ├── jumpGame.py
│ │ └── jumpGameII.py
│ ├── hard
│ │ ├── nQueens.py
│ │ ├── nQueensII.py
│ │ └── trapWater.py
│ ├── linked-list
│ │ ├── mergeLists.py
│ │ └── reverseLList.py
│ ├── medium
│ │ ├── characterReplacement.py
│ │ ├── combinationSum.py
│ │ ├── encodeDecode.py
│ │ ├── houseRobber.py
│ │ ├── houseRobberII.py
│ │ ├── lengthOfLongestSubstring.py
│ │ ├── longestCommonSubsequence.py
│ │ ├── longestConsecutiveSequence.py
│ │ ├── longestPalindromicString.py
│ │ ├── maxArea.py
│ │ ├── maxAreaIslands.py
│ │ ├── maxProfitCooldown.py
│ │ ├── maxSubArray.py
│ │ ├── maxUniqueSubArray.py
│ │ ├── minCostClimbingStairs.py
│ │ ├── minDistance.py
│ │ ├── minOperations.py
│ │ ├── numDecodings.py
│ │ ├── numsIslands.py
│ │ ├── palindromicSubstring.py
│ │ ├── permutation.py
│ │ ├── productExceptSelf.py
│ │ ├── rangeSumQuery.py
│ │ ├── subsets-ii.py
│ │ ├── subsets.py
│ │ ├── test_KClosest.py
│ │ ├── test_KthLargestArr.py
│ │ ├── topKFrequent.py
│ │ ├── triangle.py
│ │ ├── twoSumII.py
│ │ ├── uniquePaths.py
│ │ └── validSudoku.py
│ └── test_sum.py
├── readme.md
└── sean-prashad
│ ├── Javascript
│ ├── 15-binarySearch.test.js
│ ├── 16-nextGreatestLetter.test.js
│ ├── 17-avgOfLevels.test.js
│ ├── 18-minDeptht.test.js
│ ├── 19-maxDepth.test.js
│ ├── 20-isSameTree.test.js
│ ├── 21-pathSum.test.js
│ ├── 22-twoSum.test.js
│ ├── 23-invertBinaryTree.test.js
│ ├── 24-subTree.test.js
│ ├── 25-squareSortedArr.test.js
│ ├── 26-backSpaceStringCompare.test.js
│ ├── 27-majorityElement.test.js
│ └── 28-productExceptSelf.test.js
│ └── python
│ ├── 1-containsDups.py
│ ├── 10-palindromeLList.py
│ ├── 11-reverseLList.py
│ ├── 12-removeLListEl.py
│ ├── 13-removeDupsSortedLList.py
│ ├── 14-mergeTwoSortedList.py
│ ├── 15-binarySearch.py
│ ├── 16-nextGreatestLetter.py
│ ├── 17-avgOfLevels.py
│ ├── 18-minDepth.py
│ ├── 19-maxDepth.py
│ ├── 2-missingNumber.py
│ ├── 20-isSameTree.py
│ ├── 21-pathSum.py
│ ├── 22-twoSum.py
│ ├── 23-invertBinaryTree.py
│ ├── 24-subTree.py
│ ├── 25-squareSortedArr.py
│ ├── 26-backspaceStringCompare.py
│ ├── 27-majorityElement.py
│ ├── 3-findDisappearedNumbers.py
│ ├── 4-singleNumber.py
│ ├── 5-climbingStairs.py
│ ├── 6-bestTimeToSell.py
│ ├── 7-rangeSumQuery.py
│ ├── 8-hasCycle.py
│ ├── 9-middleLinkedList.py
│ └── bonus-linkedlistII.py
├── package-lock.json
├── package.json
└── readme.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | note.md
--------------------------------------------------------------------------------
/Algorithms/Dynamic-Programming/canSum.py:
--------------------------------------------------------------------------------
1 | '''
2 | https://coderbyte.com/algorithm/subset-sum-problem?stay=true
3 |
4 | The function would always return true unless the target sum is less than the
5 | smallest number in the array, which is quite a clever trick.
6 | '''
7 |
8 | import unittest
9 | memo = {}
10 | # 0(m * n) - tc | 0(m) - sc
11 |
12 | def canSum(targetSum, nums):
13 | if targetSum in memo:
14 | return memo[targetSum]
15 | if targetSum == 0:
16 | return True
17 | if targetSum < 0:
18 | return False
19 |
20 | for num in nums:
21 | res = targetSum - num
22 | if canSum(res, nums):
23 | memo[targetSum] = True
24 | return True
25 |
26 | memo[targetSum] = False
27 | return False
28 |
29 | def canSumTwo(target, nums):
30 | smallest = min(nums)
31 | if target < smallest:
32 | return False
33 | return True
34 |
35 | print('print statement', canSum(7, [2, 4]))
36 | print('print statement', canSum(7, [2, 3]))
37 |
38 | class Test(unittest.TestCase):
39 | def test_canSum(self):
40 | self.assertEqual(canSum(7, [2, 3]), True)
41 | self.assertEqual(canSum(7, [5, 3, 4, 7]), True)
42 | self.assertEqual(canSum(7, [2, 4]), False)
43 | self.assertEqual(canSum(8, [2, 3, 5]), True)
44 | self.assertEqual(canSum(300, [7, 14]), False)
45 |
46 | if __name__ == "__main__":
47 | unittest.main()
--------------------------------------------------------------------------------
/Algorithms/Dynamic-Programming/fibonacci.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | memo = {}
4 |
5 |
6 | def fib(n):
7 | if n < 0:
8 | raise Exception(f"Invalid input: {n}")
9 |
10 | if n == 0:
11 | return 0
12 |
13 | if n == 1:
14 | return 1
15 |
16 | if n in memo:
17 | return memo[n]
18 |
19 | current_fib_number = fib(n - 1) + fib(n - 2)
20 | memo[n] = current_fib_number
21 |
22 | return current_fib_number
23 |
24 |
25 | class Test(unittest.TestCase):
26 | def test_fib(self):
27 | with self.assertRaises(Exception):
28 | fib(-1)
29 | self.assertEqual(fib(9), 34)
30 | self.assertEqual(fib(50), 12586269025)
31 | self.assertEqual(fib(10), 55)
32 | self.assertEqual(fib(0), 0)
33 | self.assertEqual(fib(1), 1)
34 | self.assertEqual(fib(6), 8)
35 | self.assertEqual(fib(37), 24157817)
36 | self.assertEqual(fib(2), 1)
37 |
38 |
39 | if __name__ == "__main__":
40 | unittest.main()
41 |
--------------------------------------------------------------------------------
/Algorithms/Loops/nestedLoops.py:
--------------------------------------------------------------------------------
1 | matrix = [
2 | [1, 2, 3],
3 | [4, 5, 6],
4 | [8, 7, 9],
5 | [-1, -4, 0]
6 | ]
7 |
8 | for i in range(len(matrix)):
9 | for j in range(len(matrix[0])):
10 | print(i, j)
11 |
12 |
--------------------------------------------------------------------------------
/coding-interview/amazon/process-dates.test.js:
--------------------------------------------------------------------------------
1 | // This was a coding test by amazon
2 |
3 | describe('process date', () => {
4 | it('converts date string to YYYY-MM-DD format', () => {
5 | expect(processDates([
6 | '1st Apr 2022', '4th Aug 2001',
7 | '1st Mar 1974', '22nd Jan 2013',
8 | '7th Apr 1904'
9 | ]))
10 | .toEqual([
11 | '2022-04-01', '2001-08-04',
12 | '1974-03-01', '2013-01-22',
13 | '1904-04-07'
14 | ]);
15 | });
16 | });
17 |
18 | const months = [
19 | 'Jan', 'Feb', 'Mar', 'Apr',
20 | 'May', 'Jun', 'Jul', 'Aug',
21 | 'Sep', 'Oct', 'Nov', 'Dec'
22 | ];
23 |
24 | const processDates = (dates) => {
25 | let processedDate = [];
26 | let month, day, year;
27 |
28 | for (let date of dates) {
29 | date = date.split(' ');
30 |
31 | for (d of date) {
32 | day = processDay(date[0]);
33 | month = processMonth(date[1]);
34 | year = date[2];
35 | }
36 | processedDate.push(year + '-' + month + '-' + day);
37 | }
38 | return processedDate;
39 | };
40 |
41 | const addZero = (value) => {
42 | value = value.toString().split('');
43 | if (value.length < 2) return '0' + value;
44 | else return value.join('');
45 | };
46 |
47 | const processMonth = (month) => {
48 | month = months.indexOf(month) + 1;
49 | return addZero(month);
50 | };
51 |
52 | const processDay = (day) => {
53 | let value = [];
54 | for (let d of day) {
55 | d = parseInt(d);
56 | if (d) value += d;
57 | }
58 | return addZero(value);
59 | };
--------------------------------------------------------------------------------
/coding-interview/meta/rotational-ciphers.test.js:
--------------------------------------------------------------------------------
1 | /* Run test: npm test ./meta/rotational-ciphers.test.js
2 |
3 | https://www.facebookrecruiting.com/portal/coding_practice_question/?problem_id=238827593802550&ppid=454615229006519&practice_plan=1
4 |
5 |
6 | 0(n) - time | 0(1) - space
7 | */
8 |
9 | const { ord, ordFrom, isUpper, isLower } = require('js-ord')
10 |
11 | describe('rotational ciphers', () => {
12 | it('encrypts a string by return the third value of every string and number', () => {
13 | expect(rotationalCipher("Zebra-493?", 3)).toBe("Cheud-726?")
14 | expect(rotationalCipher("abcdefghijklmNOPQRSTUVWXYZ0123456789", 39)).toBe("nopqrstuvwxyzABCDEFGHIJKLM9012345678")
15 | })
16 | })
17 |
18 | const rotationalCipher = (string, rotation) => {
19 | let cipher = []
20 | for (let str of string) {
21 | let validChar = str.match(/[a-zA-Z0-9]/g)
22 |
23 | if (str === '0') {
24 | cipher.push(9)
25 | }
26 | else if (Number(str)) {
27 | str = (Number(str) + rotation) % 10
28 | cipher.push(str)
29 | }
30 | else if (validChar && isUpper(str)) {
31 | str = ((ord(str) - ord('A')) + rotation) % 26
32 | cipher.push(ordFrom(ord('A') + str))
33 | }
34 | else if (validChar && isLower(str)) {
35 | str = ((ord(str) - ord('a')) + rotation) % 26
36 | cipher.push(ordFrom(ord('a') + str))
37 | }
38 | else {
39 | cipher.push(str)
40 | }
41 | }
42 |
43 | return cipher.join('')
44 | }
--------------------------------------------------------------------------------
/coverage/clover.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/coverage/coverage-final.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/coverage/lcov-report/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blossom-babs/Data-structures-and-algorithm/027b4e7a5037a5897789eafebbf828899313feff/coverage/lcov-report/favicon.png
--------------------------------------------------------------------------------
/coverage/lcov-report/prettify.css:
--------------------------------------------------------------------------------
1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
2 |
--------------------------------------------------------------------------------
/coverage/lcov-report/sort-arrow-sprite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blossom-babs/Data-structures-and-algorithm/027b4e7a5037a5897789eafebbf828899313feff/coverage/lcov-report/sort-arrow-sprite.png
--------------------------------------------------------------------------------
/coverage/lcov.info:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blossom-babs/Data-structures-and-algorithm/027b4e7a5037a5897789eafebbf828899313feff/coverage/lcov.info
--------------------------------------------------------------------------------
/data-structures/binary-search-trees/BST-counting-occurrence.test.js:
--------------------------------------------------------------------------------
1 | //TEST: npm test ./data-structures/binary-search-trees/BST-counting-occurrence.test.js
2 |
3 | describe('#BST count occurrencr', () => {
4 | let bst;
5 |
6 | beforeEach(() => {
7 | bst = new BST()
8 | bst.insertDups(bst.root, 23); bst.insertDups(bst.root, 16)
9 | bst.insertDups(bst.root, 23); bst.insertDups(bst.root, 16)
10 | bst.insertDups(bst.root, 22); bst.insertDups(bst.root, 20);
11 | bst.insertDups(bst.root, 23); bst.insertDups(bst.root, 20);
12 | })
13 |
14 | it('increases the count of a node key', () => {
15 | expect(bst.root.count).toBe(3)
16 | expect(bst.root.left.right.left.count).toBe(2)
17 | expect(bst.size).toBe(4)
18 | })
19 | })
20 |
21 | class Node {
22 | constructor(data) {
23 | this.data = data;
24 | this.count = 1
25 | this.left = this.right = null
26 | }
27 | }
28 |
29 | class BST {
30 | constructor() {
31 | this.root = null
32 | this.size = 0
33 |
34 | }
35 |
36 | insertDups(root, data) {
37 | let newNode = new Node(data)
38 |
39 | if (!root) {
40 | this.root = newNode
41 | this.size++
42 | return root
43 | }
44 |
45 | if (data === root.data) {
46 | root.count++
47 | return root
48 | } else if (data < root.data) {
49 | if (!root.left) {
50 | root.left = newNode
51 | this.size++
52 | }
53 | else this.insertDups(root.left, data)
54 | } else {
55 | if (!root.right) {
56 | root.right = newNode
57 | this.size++
58 | }
59 | else this.insertDups(root.right, data)
60 | }
61 | return root
62 | }
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/data-structures/binary-search-trees/BSTremoveNode.test.js:
--------------------------------------------------------------------------------
1 | //TEST: npm test ./data-structures/binary-search-trees/BSTremoveNode.test.js
2 |
3 | const { findMin } = require("./BSTsearches.test");
4 | const BST = require("./traverseBST.test");
5 |
6 |
7 | describe('#BST remove node', () => {
8 | let bst;
9 |
10 | beforeEach(() => {
11 | bst = new BST()
12 | bst.insert(bst.root, 23); bst.insert(bst.root, 16)
13 | bst.insert(bst.root, 45); bst.insert(bst.root, 37)
14 | bst.insert(bst.root, 99); bst.insert(bst.root, 3)
15 | bst.insert(bst.root, 22); bst.insert(bst.root, 20);
16 | })
17 |
18 | it('removes a leaf node', () => {
19 | expect(removeNode(bst.root, 3).left.left).toBe(null)
20 | })
21 |
22 | it('removes a node with one child', () => {
23 | expect(removeNode(bst.root, 22).left.right.data).toBe(20)
24 | })
25 | })
26 |
27 | const removeNode = (root, data) => {
28 |
29 | if (!root) return null
30 | else if (data < root.data) {
31 | root.left = removeNode(root.left, data)
32 | } else if (data > root.data) {
33 | root.right = removeNode(root.right, data)
34 | } else {
35 | if ((!root.left && !root.right)) root = null
36 | else if (!root.left) {
37 | root = root.right
38 | } else if (!root.right) {
39 | root = root.left
40 | } else {
41 | temp = findMin(root.right)
42 | root.data = temp.data
43 | root.right = removeNode(root.right, temp.data)
44 | }
45 | }
46 |
47 | return root
48 | }
--------------------------------------------------------------------------------
/data-structures/binary-search-trees/BSTsearches.test.js:
--------------------------------------------------------------------------------
1 | //TEST: npm test ./data-structures/binary-search-trees/BSTsearches.test.js
2 |
3 | const BST = require("./traverseBST.test");
4 |
5 |
6 | describe('#BST Searches', () => {
7 | let bst;
8 |
9 | beforeEach(() => {
10 | bst = new BST()
11 | bst.insert(bst.root, 23); bst.insert(bst.root, 16)
12 | bst.insert(bst.root, 45); bst.insert(bst.root, 37)
13 | bst.insert(bst.root, 99); bst.insert(bst.root, 3)
14 | bst.insert(bst.root, 22)
15 | })
16 |
17 | it('find the minimun element in a BST search tree', () => {
18 | expect(findMin(bst.root).data).toBe(3)
19 | })
20 |
21 | it('find the maximum element in a BST search tree', () => {
22 | expect(findMax(bst.root)).toBe(99)
23 | })
24 |
25 | it('finds a specific value in the tree', () => {
26 | expect(findVal(bst.root, 45)).toBe(true)
27 | expect(findVal(bst.root, 95)).toBe(null)
28 | })
29 | })
30 |
31 |
32 |
33 | const findMin = (root) => {
34 | if (!root) return -1
35 |
36 | else if (root.left) { return findMin(root.left) }
37 |
38 | else return root
39 | }
40 |
41 | const findMax = (root) => {
42 | if (!root) return -1
43 |
44 | else if (root.right) {
45 | return findMax(root.right)
46 | }
47 |
48 | else return root.data
49 | }
50 |
51 | const findVal = (root, data) => {
52 | if (!root) return null
53 |
54 | if (data === root.data) return true
55 | else if (data < root.data) return findVal(root.left, data)
56 | else return findVal(root.right, data)
57 | }
58 |
59 | module.exports = { findMin }
--------------------------------------------------------------------------------
/data-structures/binary-search-trees/insertBST.test.js:
--------------------------------------------------------------------------------
1 | //Test: npm test ./data-structures/binary-search-trees/insertBST.test.js
2 |
3 | describe('Binary Search Trees', () => {
4 | let bNode;
5 |
6 | beforeEach(() => {
7 | bNode = new BST()
8 | })
9 |
10 | it('inserts into a binary search tree', () => {
11 | bNode.insert(4); bNode.insert(3); bNode.insert(5); bNode.insert(2)
12 | expect(bNode.root.data).toBe(4)
13 | expect(bNode.root.left.left.data).toBe(2)
14 | })
15 | })
16 |
17 | class BNode {
18 | constructor(data, left, right) {
19 | this.data = data
20 | this.left = left
21 | this.right = right
22 | }
23 |
24 | show() {
25 | return this.data
26 | }
27 | }
28 |
29 | class BST {
30 | constructor() {
31 | this.root = null
32 | }
33 |
34 | // inserts iteratively
35 | insert(data) {
36 | let newNode = new BNode(data, null, null)
37 |
38 | if (!this.root) {
39 | this.root = newNode
40 | } else {
41 |
42 | let current = this.root
43 | let parent;
44 |
45 | while (true) {
46 | parent = current
47 |
48 | if (data < current.data) {
49 | current = current.left
50 |
51 | if (!current) {
52 | parent.left = newNode
53 | break;
54 | }
55 | } else {
56 | current = current.right
57 |
58 | if (!current) {
59 | parent.right = newNode
60 | break;
61 | }
62 | }
63 | }
64 | }
65 | }
66 | }
67 |
68 | module.exports = BNode;
--------------------------------------------------------------------------------
/data-structures/binary-search-trees/python/insertIntoTree.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blossom-babs/Data-structures-and-algorithm/027b4e7a5037a5897789eafebbf828899313feff/data-structures/binary-search-trees/python/insertIntoTree.py
--------------------------------------------------------------------------------
/data-structures/binary-search-trees/traverseBST.test.js:
--------------------------------------------------------------------------------
1 |
2 | const BNode = require("./insertBST.test");
3 |
4 | /* There are 4 types of traversal
5 |
6 | 1. inorder traversal
7 | 2. preorder traversal
8 | 3. postorder traversal
9 |
10 | */
11 |
12 |
13 | // inserting using recursion
14 | class BST {
15 |
16 | constructor() {
17 | this.root = null
18 | }
19 |
20 | inOrder(node) {
21 | if (node) {
22 | this.inOrder(node.left)
23 | console.log(node.data)
24 | this.inOrder(node.right)
25 | }
26 | }
27 |
28 | preOrder(node) {
29 | if (node) {
30 | console.log(node.data)
31 | this.preOrder(node.left)
32 | this.inOrder(node.right)
33 | }
34 | }
35 |
36 | postOrder(node) {
37 | if (node) {
38 | this.postOrder(node.left)
39 | this.postOrder(node.right)
40 | console.log(node.data)
41 | }
42 | }
43 |
44 | insert(root, data) {
45 | let newNode = new BNode(data)
46 |
47 | if (!root) {
48 | this.root = newNode
49 | return root
50 | }
51 |
52 | if (data < root.data) {
53 | if (!root.left) root.left = newNode
54 | else this.insert(root.left, data)
55 | } else {
56 | if (!root.right) root.right = newNode
57 | else this.insert(root.right, data)
58 | }
59 |
60 | return root
61 | }
62 |
63 |
64 | }
65 |
66 | module.exports = BST
--------------------------------------------------------------------------------
/data-structures/binary-trees/javascript/binaryTree.test.js:
--------------------------------------------------------------------------------
1 | // create a Node class
2 |
3 | class Node {
4 | constructor(data) {
5 | this.data = data
6 | this.left = null
7 | this.right = null
8 | }
9 |
10 | }
11 |
12 | class BinaryTree {
13 | constructor() {
14 | this.root = null
15 | }
16 |
17 |
18 | insert(root, data) {
19 | let newNode = new Node(data)
20 |
21 | if (root === null) {
22 | this.root = newNode
23 | return root
24 | }
25 |
26 |
27 | if (data < this.root.data) {
28 | if (this.root.left === null) {
29 | this.root.left = newNode
30 | } else {
31 | this.insert(root.left, data)
32 | }
33 | }
34 |
35 | if (data > this.root.data) {
36 | if (this.root.right === null) {
37 | this.root.right = newNode
38 | } else {
39 | this.insert(root.right, data)
40 | }
41 | }
42 |
43 | }
44 |
45 | preorder(root){
46 | console.log(root.data)
47 | if(root.left) this.preorder(root.left)
48 | if(root.right) this.preorder(root.right)
49 | }
50 |
51 | inorder(root){
52 | if(root.left) this.preorder(root.left)
53 | console.log(root.data)
54 | if(root.right) this.preorder(root.right)
55 | }
56 |
57 | postorder(root){
58 | if(root.left) this.preorder(root.left)
59 | if(root.right) this.preorder(root.right)
60 | console.log(root.data)
61 | }
62 |
63 | bfs(root){
64 | let queue = [root]
65 |
66 | while(queue.length){
67 | let node = queue.shift()
68 | console.log(node.data)
69 | if(node.left) queue.push(node.left)
70 | if(node.right) queue.push(node.right)
71 | }
72 | }
73 | }
74 |
75 | let tree = new BinaryTree()
76 | tree.insert(tree.root, 10)
77 | tree.insert(tree.root, 2)
78 | tree.insert(tree.root, 20)
79 | // tree.insert(tree.root, 15)
80 | // tree.insert(tree.root, 87)
81 | // tree.insert(tree.root, 7)
82 | // tree.insert(tree.root, 17)
83 | // tree.inorder(tree.root)
84 | tree.bfs(tree.root)
--------------------------------------------------------------------------------
/data-structures/binary-trees/python/binarySearchTree.py:
--------------------------------------------------------------------------------
1 | # create a python node
2 |
3 | class Node:
4 | def __init__(self, data):
5 | self.root = data
6 | self.left = None
7 | self.right = None
8 |
9 | def insert(self, data):
10 | if self.root:
11 | if data < self.root:
12 | if self.left is None:
13 | self.left = Node(data)
14 | else:
15 | self.left.insert(data)
16 | if data > self.root:
17 | if self.right is None:
18 | self.right = Node(data)
19 | else:
20 | self.right.insert(data)
21 |
22 | else:
23 | self.root = data
24 |
25 | def inorder(self, root):
26 | res = []
27 | if root:
28 | res = self.inorder(root.left)
29 | res.append(root.root)
30 | res = res + self.inorder(root.right)
31 | return res
32 |
33 |
34 |
35 |
36 |
37 | '''
38 | 10
39 | / \
40 | 2 20
41 | \ / \
42 | 7 15 87
43 | \
44 | 17
45 | '''
46 |
47 |
48 | tree = Node(10)
49 | tree.insert(2)
50 | tree.insert(20)
51 | tree.insert(15)
52 | tree.insert(87)
53 | tree.insert(7)
54 | tree.insert(17)
55 |
56 | print(tree.inorder(tree))
57 |
58 |
--------------------------------------------------------------------------------
/data-structures/graphs/connectCompCount.py:
--------------------------------------------------------------------------------
1 | '''
2 | source: structy
3 |
4 | CONNECTED COMPONENTS COUNT
5 |
6 | write a function, connectedComponentCount, that takes in the adjacency list of an undirected graph
7 | (that is you need a set to avoid cyclic graphs).
8 | The function should return the number of connected components in the graph.
9 |
10 | test__00:
11 | connectedComponentsCount({
12 | 0: [8, 1, 5],
13 | 1: [0],
14 | 5: [0, 8],
15 | 8: [0, 5],
16 | 2: [3, 4],
17 | 3: [2, 4],
18 | 4: [3, 2]
19 | }) # 2
20 | '''
21 | import unittest
22 | # 0(e) tc | 0(n) - sc
23 |
24 | cc = {
25 | 0: [8, 1, 5],
26 | 1: [0],
27 | 5: [0, 8],
28 | 8: [0, 5],
29 | 2: [3, 4],
30 | 3: [2, 4],
31 | 4: [3, 2]
32 | } # 2
33 |
34 | cc_2 = {
35 | 3: [],
36 | 4: [6],
37 | 6: [4,5,7,8],
38 | 8: [6],
39 | 7: [6],
40 | 5: [6],
41 | 1: [2],
42 | 2: [1]
43 | } # 3
44 |
45 |
46 | def connectedComponentsCount(graph):
47 | count, visited = 0, set()
48 | for key in graph:
49 | if dfs(graph, key, visited) == True:
50 | count += 1
51 | return count
52 |
53 |
54 | def dfs(graph, key, visited):
55 | if key in visited:
56 | return False
57 | visited.add(key)
58 | for neighbor in graph[key]:
59 | dfs(graph, neighbor, visited)
60 | return True
61 |
62 |
63 | class Test(unittest.TestCase):
64 | def test_connectComp(self):
65 | self.assertEqual(connectedComponentsCount(cc), 2)
66 | self.assertEqual(connectedComponentsCount(cc_2), 3)
67 |
68 | if __name__ == "__main__":
69 | unittest.main()
--------------------------------------------------------------------------------
/data-structures/graphs/traversals_bfs.py:
--------------------------------------------------------------------------------
1 | '''
2 | Breadth first traversal
3 | '''
4 |
5 | import collections
6 |
7 | adjacency_list = {
8 | 'a': ['b', 'c'],
9 | 'b': ['d'],
10 | 'c': ['e'],
11 | 'd': ['f'],
12 | 'e': [],
13 | 'f': []
14 | }
15 |
16 | def dfs(graph, start):
17 | queue = collections.deque([start]) # add the starting item to the queue
18 | while queue: # run this loop until the queue is empty
19 | curr = queue.popleft() # remove the FIRST item in the queue FIFO
20 | print(curr) # print the item
21 |
22 | for item in graph[curr]: # add all the neighbors of the curr item to the queue
23 | queue.append(item)
24 |
25 | dfs(adjacency_list, 'a')
--------------------------------------------------------------------------------
/data-structures/graphs/traversals_dfs.py:
--------------------------------------------------------------------------------
1 | '''
2 | Depth first traversal
3 | '''
4 |
5 | # Iteratively
6 | adjacency_list = {
7 | 'a': ['b', 'c'],
8 | 'b': ['d'],
9 | 'c': ['e'],
10 | 'd': ['f'],
11 | 'e': [],
12 | 'f': []
13 | }
14 |
15 | def dfs(graph, start):
16 | stack_ds = [start] # add the starting item to the stack
17 |
18 | while stack_ds: # run this loop until the stack is empty
19 | curr = stack_ds.pop() # remove the last item in the stack LIFO
20 | print(curr) # print the item
21 |
22 | for item in graph[curr]: # add the neighbors of the curr item to the stack
23 | stack_ds.append(item)
24 |
25 | dfs(adjacency_list, 'a')
26 |
27 | # recursively
28 |
29 | def dfs_recursive(graph, start):
30 | print(start)
31 | for item in graph[start]:
32 | dfs_recursive(graph, item)
33 |
34 | dfs_recursive(adjacency_list, 'a')
--------------------------------------------------------------------------------
/data-structures/heaps/Heap.test.js:
--------------------------------------------------------------------------------
1 | class Heap {
2 | constructor() {
3 | this.items = []
4 | this.size = 0
5 | }
6 | swap(idx1, idx2) {
7 | let temp = this.items[idx1]
8 | this.items[idx1] = this.items[idx2]
9 | this.items[idx2] = temp
10 | }
11 | parentIdx(idx) {
12 | return Math.floor((idx - 1) / 2)
13 | }
14 | leftChildIdx(idx) {
15 | return (idx * 2) + 1
16 | }
17 | rightChildIdx(idx) {
18 | return (idx * 2) + 2
19 | }
20 | parent(idx) {
21 | return this.items[this.parentIdx(idx)]
22 | }
23 | leftChild(idx) {
24 | return this.items[this.leftChildIdx(idx)]
25 | }
26 | rightChild(idx) {
27 | return this.items[this.rightChildIdx(idx)]
28 | }
29 |
30 | hasParent(idx) {
31 | return this.parentIdx(idx) >= 0
32 | }
33 |
34 | hasLeftChild(idx){
35 | return this.leftChildIdx(idx) < this.size
36 | }
37 |
38 | hasRightChild(idx){
39 | return this.rightChildIdx(idx) < this.size
40 | }
41 | }
42 |
43 | module.exports = Heap
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/data-structures/heaps/MinHeap.test.js:
--------------------------------------------------------------------------------
1 | //TEST: npm test ./data-structures/heaps/MinHeap.test.js
2 | const Heap = require("./Heap.test");
3 |
4 | describe('#Min-Heap', () => {
5 | let mh;
6 |
7 | beforeEach(() => {
8 | mh = new MinHeap()
9 | mh.insert(1); mh.insert(10);
10 | mh.insert(5); mh.insert(100);
11 | mh.insert(8);
12 | })
13 |
14 | it('inserts data to heap', () => {
15 | expect(mh.items).toStrictEqual([1, 8, 5, 100, 10])
16 | expect(mh.items).toHaveLength(5)
17 | })
18 |
19 | it('removed data from heap', () => {
20 | expect(mh.removeMin()).toBe(5)
21 | })
22 | })
23 |
24 | class MinHeap extends Heap {
25 | insert(data) {
26 | this.items[this.size] = data
27 | this.size++
28 | this.heapifyUp(this.size - 1)
29 | }
30 |
31 | heapifyUp(idx) {
32 | if (this.hasParent(idx) && this.parent(idx) > this.items[idx]) {
33 | this.swap(this.parentIdx(idx), idx)
34 | this.heapifyUp(this.parentIdx, idx)
35 | }
36 | }
37 |
38 | removeMin() {
39 | if (this.size === 0) {
40 | throw new Error('Empty Heap')
41 | }
42 |
43 | let data = this.items[0]
44 | this.items[0] = this.items[this.size - 1]
45 | this.size--
46 | this.heapifyDown(0)
47 | return data
48 | }
49 |
50 | heapifyDown(idx) {
51 | let smallest = idx
52 |
53 | if (this.hasLeftChild(idx) && this.items[smallest] > this.leftChild(idx)) {
54 | smallest = this.leftChildIdx(idx)
55 | }
56 |
57 | if (this.hasRightChild && this.items[smallest] > this.rightChildIdx(idx)) {
58 | smallest = this.rightChildIdx(idx)
59 | }
60 |
61 | if (smallest !== idx) {
62 | this.swap(idx, smallest)
63 | this.heapifyDown(smallest)
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/data-structures/queue/ImplementAQueueDs.test.js:
--------------------------------------------------------------------------------
1 | // Implement a Queue data structure
2 | // Test: npm test ./data-structures/queue/ImplementAQueueDs.test.js
3 |
4 | describe('Queue', () => {
5 | let queue;
6 |
7 | beforeEach(() => {
8 | queue = new Queue()
9 | })
10 |
11 | it('adds elemets to a queue', () => {
12 | queue.enqueue(5); queue.enqueue(7); queue.enqueue(8); queue.enqueue(7)
13 | expect(queue.datastore).toStrictEqual([5, 7, 8, 7])
14 | expect(queue.size).toBe(4)
15 | })
16 | })
17 |
18 | class Queue {
19 | constructor() {
20 | this.datastore = []
21 | this.size = 0
22 | }
23 |
24 | enqueue(data) {
25 | this.datastore[this.datastore.length++] = data
26 | this.size++
27 | return this.datastore
28 | }
29 |
30 | dequeue() {
31 | this.datastore.splice(0, 1)
32 | this.size--
33 | return this.datastore
34 | }
35 |
36 | peek() {
37 | return this.datastore[0]
38 | }
39 |
40 | backPeek() {
41 | return this.datastore[this.size - 1]
42 | }
43 |
44 | isEmpty() {
45 | return this.size === 0
46 | }
47 |
48 | display() {
49 | let items = ''
50 | for (let item of this.datastore) {
51 | items += item + '\n'
52 | }
53 | return items
54 | }
55 | }
56 |
57 | // const queue = new Queue()
58 | // queue.enqueue(7)
59 | // queue.enqueue(8)
60 | // queue.enqueue(9)
61 | // console.log( queue)
62 | // queue.dequeue()
63 | // console.log( queue.display())
--------------------------------------------------------------------------------
/data-structures/readme.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blossom-babs/Data-structures-and-algorithm/027b4e7a5037a5897789eafebbf828899313feff/data-structures/readme.md
--------------------------------------------------------------------------------
/hackerRank/Arrays/readme.md:
--------------------------------------------------------------------------------
1 | ## Index of the solution to [Hackkerrank Array challenge](https://www.hackerrank.com/domains/data-structures?filters%5Bsubdomains%5D%5B%5D=arrays)
2 |
3 | | Index | Question | Solution & Test |
4 | | ----- | -------- | --------------- |
5 | | 1. | [Reverse an array of integers](https://www.hackerrank.com/challenges/arrays-ds/problem?isFullScreen=true) | [solution](https://github.com/blossom-babs/Data-structures-and-algorithm/blob/main/hackerRank/Arrays/reverseIntArr.test.js) |
--------------------------------------------------------------------------------
/hackerRank/Arrays/reverseIntArr.test.js:
--------------------------------------------------------------------------------
1 | // https://www.hackerrank.com/challenges/arrays-ds/problem?isFullScreen=true
2 | // Test: npm test ./hackerRank/Arrays/reverseIntArr.test.js
3 | // 0(n) - time | 0(1) - space
4 |
5 | describe('reverse an array of integers', () => {
6 | it('returns an array of reversed integers', () => {
7 | expect(reverseArray([2,5,4])).toStrictEqual([4,5,2])
8 | expect(reverseArray([0])).toStrictEqual([0])
9 | })
10 | })
11 |
12 | const reverseArray = arr => {
13 | let reversed = []
14 |
15 | for(let i = arr.length - 1; i >= 0; i--){
16 | reversed.push(arr[i])
17 | }
18 |
19 | return reversed
20 | }
--------------------------------------------------------------------------------
/hackerRank/linkedList/compareTwoList.js:
--------------------------------------------------------------------------------
1 | /* DAY 8 OF A 10-DAY CODE CHALLENGE WITH SODIQ AYILARA MD
2 |
3 | https://www.hackerrank.com/challenges/compare-two-linked-lists/problem?isFullScreen=true
4 |
5 | Test: npm test ./hackerRank/linkedList/compareTwoList.test.js
6 | */
7 |
8 | // Complete the CompareLists function below.
9 |
10 | /*
11 | * For your reference:
12 | *
13 | * SinglyLinkedListNode {
14 | * int data;
15 | * SinglyLinkedListNode next;
16 | * }
17 | *
18 | */
19 | function CompareLists(llist1, llist2) {
20 | let list1 = llist1
21 | let list2 = llist2
22 |
23 | while (list1 && list2) {
24 | if (list1.data === list2.data) {
25 | list1 = list1.next
26 | list2 = list2.next
27 | } else {
28 | return 0
29 | }
30 | }
31 | return list1 || list2 ? 0 : 1
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/hackerRank/linkedList/compareTwoList.test.js:
--------------------------------------------------------------------------------
1 | /* Test: npm test ./hackerRank/linkedList/compareTwoList.test.js */
2 |
3 | describe('compare lists', () => {
4 |
5 | let list, list1, list2
6 |
7 | beforeEach(() => {
8 | list = new SinglyLinkedList()
9 | list1 = new SinglyLinkedList()
10 | list2 = new SinglyLinkedList()
11 | })
12 |
13 | it('returns 0 if lists are not the same', () => {
14 | list1.insert(10)
15 | list1.insert(20)
16 | list1.insert(30)
17 | list2.insert(10)
18 | list2.insert(20)
19 | expect(list.compare(list1, list2)).toBe(0)
20 | })
21 |
22 | it('returns 1 if list are the same', () => {
23 | list1.insert(10)
24 | list1.insert(20)
25 | list2.insert(10)
26 | list2.insert(20)
27 | expect(list.compare(list1, list2)).toBe(1)
28 | })
29 | })
30 |
31 | class Node {
32 | constructor(data) {
33 | this.data = data
34 | this.next = null
35 | }
36 | }
37 |
38 | class SinglyLinkedList {
39 | insert(data) {
40 | let newNode = new Node(data)
41 |
42 | if (!this.head) {
43 | this.head = newNode
44 | return this.head
45 | }
46 |
47 | let current = this.head
48 | this.head = newNode
49 | this.head.next = current
50 |
51 | return this.head
52 | }
53 |
54 | compare(list1, list2) {
55 | let head1 = list1.head
56 | let head2 = list2.head
57 |
58 | while (head1 && head2) {
59 | if (head1.data !== head2.data) {
60 | return 0
61 | }
62 | head1 = head1.next
63 | head2 = head2.next
64 | }
65 |
66 | return head1 || head2 ? 0 : 1
67 | }
68 | }
--------------------------------------------------------------------------------
/hackerRank/linkedList/cycleDetection.js:
--------------------------------------------------------------------------------
1 | // https://www.hackerrank.com/challenges/detect-whether-a-linked-list-contains-a-cycle/problem
2 | // Test: npm test ./hackerRank/linkedList/cycleDetection.test.js
3 | // 0(n) - space | 0(n) - time
4 |
5 | function hasCycle(head){
6 | let list = head
7 | let hash = new Map()
8 |
9 | while(list){
10 | if(hash.has(list.data)){return 1}
11 | else {
12 | hash.set(list.data, true)
13 | list = list.next
14 | }
15 | }
16 | return 0
17 | }
--------------------------------------------------------------------------------
/hackerRank/linkedList/cycleDetection.test.js:
--------------------------------------------------------------------------------
1 | // https://www.hackerrank.com/challenges/detect-whether-a-linked-list-contains-a-cycle/problem
2 | // Test: npm test ./hackerRank/linkedList/cycleDetection.test.js
3 | // 0(n) - space | 0(n) - time
4 |
5 | describe('cycle detection', () => {
6 | let list;
7 | beforeEach(() => {
8 | list = new SinglyLinkedList()
9 | })
10 | it('returns 1 if there is a cycle detection', () => {
11 | list.insert(1)
12 | list.insert(-1)
13 | list.insert(1)
14 | let cycle = list.hasCycle()
15 | expect(cycle).toStrictEqual(1)
16 | })
17 | it('returns 0 if there is no cycle detection', () => {
18 | list.insert(1)
19 | list.insert(2)
20 | list.insert(3)
21 | let cycle = list.hasCycle()
22 | expect(cycle).toStrictEqual(0)
23 | })
24 | })
25 |
26 | class Node {
27 | constructor(data) {
28 | this.data = data
29 | this.next = null
30 | }
31 | }
32 |
33 | class SinglyLinkedList {
34 | insert(data) {
35 | let newNode = new Node(data)
36 | if (!this.head) {
37 | this.head = newNode
38 | return this.head
39 | }
40 | let current = this.head
41 | while (current.next) {
42 | current = current.next
43 | }
44 | current.next = newNode
45 | return current
46 | }
47 |
48 | hasCycle() {
49 | let list = this.head
50 | let hash = new Map()
51 | while (list) {
52 | if (hash.has(list.data)) { return 1 }
53 | else { hash.set(list.data, true) }
54 | list = list.next
55 | }
56 | return 0
57 | }
58 | }
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/hackerRank/linkedList/deleteNodeAtPos.js:
--------------------------------------------------------------------------------
1 | /* DAY 5 OF A 10-DAY LINKED LIST CHALLENGE WITH SODIQ AYILARA MD
2 |
3 | https://www.hackerrank.com/challenges/delete-a-node-from-a-linked-list/problem?isFullScreen=true
4 |
5 | Test: npm test ./hackerRank/linkedList/deleteNodeAtPos.test.js
6 |
7 | 0(n) - time | 0(1) - space
8 | */
9 |
10 |
11 | /*
12 | * Complete the 'deleteNode' function below.
13 | *
14 | * The function is expected to return an INTEGER_SINGLY_LINKED_LIST.
15 | * The function accepts following parameters:
16 | * 1. INTEGER_SINGLY_LINKED_LIST llist
17 | * 2. INTEGER position
18 | */
19 |
20 | /*
21 | * For your reference:
22 | *
23 | * SinglyLinkedListNode {
24 | * int data;
25 | * SinglyLinkedListNode next;
26 | * }
27 | *
28 | */
29 | function deleteNode(llist, position) {
30 | let nxt;
31 |
32 | if (position === 0) {
33 | nxt = llist.next
34 | llist = nxt
35 | return llist
36 | }
37 |
38 | let count = 0
39 | let current = llist
40 |
41 | while (current) {
42 | if (count === position - 1) {
43 | nxt = current.next.next
44 | current.next = nxt
45 | }
46 | current = current.next
47 | count++
48 | }
49 | return llist
50 | }
51 |
--------------------------------------------------------------------------------
/hackerRank/linkedList/deleteNodeAtPos.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | TEST: npm test ./hackerRank/linkedList/deleteNodeAtPos.test.js
3 | */
4 |
5 | describe('delete node', () => {
6 | it('deletes a node at a given position and returns the head', () => {
7 | const list = new SinglyLinkedList()
8 | list.insert(10)
9 | const deleteNode = list.delete(0)
10 | expect(deleteNode).toBe(null)
11 | })
12 | })
13 |
14 | class Node{
15 | constructor(data){
16 | this.data = data
17 | this.next = null
18 | }
19 | }
20 |
21 | class SinglyLinkedList{
22 | insert(data){
23 | let newNode = new Node(data)
24 |
25 | if(!this.head){
26 | this.head = newNode
27 | return this.head
28 | }
29 |
30 | let current = this.head
31 |
32 | while(current.next){
33 | current = current.next
34 | }
35 |
36 | current.next = newNode
37 | return current
38 | }
39 |
40 | delete(position){
41 | let nxt;
42 |
43 | if(position === 0){
44 | nxt = this.head.next
45 | this.head = nxt
46 | return this.head
47 | }
48 |
49 | let current = this.head
50 | let count = 0
51 |
52 | while(current){
53 | if(count === position - 1){
54 | nxt = current.next.next
55 | current.next = nxt
56 | }
57 | current = current.next
58 | count++
59 | }
60 | return this.head
61 | }
62 | }
--------------------------------------------------------------------------------
/hackerRank/linkedList/getNodeValue.js:
--------------------------------------------------------------------------------
1 | // day 10 linked list challenge
2 | //https://www.hackerrank.com/challenges/get-the-value-of-the-node-at-a-specific-position-from-the-tail/problem?isFullScreen=true
3 | /*
4 | * Complete the 'getNode' function below.
5 | *
6 | * The function is expected to return an INTEGER.
7 | * The function accepts following parameters:
8 | * 1. INTEGER_SINGLY_LINKED_LIST llist
9 | * 2. INTEGER positionFromTail
10 | */
11 |
12 | /*
13 | * For your reference:
14 | *
15 | * SinglyLinkedListNode {
16 | * int data;
17 | * SinglyLinkedListNode next;
18 | * }
19 | *
20 | */
21 |
22 | // 0(n) - space | 0(n) - time
23 | // Test: npm test ./hackerRank/linkedList/getNodeValue.test.js
24 |
25 | function getNode(llist, positionFromTail) {
26 | let hash = {}; let count = -1; let length = 0
27 |
28 | while (llist) {
29 | count++
30 | hash[count] = llist.data
31 | length = Math.max(length, count)
32 | llist = llist.next
33 | }
34 | return hash[length - positionFromTail]
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/hackerRank/linkedList/getNodeValue.test.js:
--------------------------------------------------------------------------------
1 | //www.hackerrank.com/challenges/get-the-value-of-the-node-at-a-specific-position-from-the-tail/problem?isFullScreen=true
2 | // Test: npm test ./hackerRank/linkedlist/getNodeValue.test.js
3 |
4 | describe('get node value', () => {
5 | it('return the number at the node 3 from the tail position', () => {
6 | const list = new SinglyLinkedList()
7 | list.insert(10)
8 | list.insert(120)
9 | list.insert(30)
10 | list.insert(40)
11 | list.insert(50)
12 | let pos3 = list.getNodeValue(3)
13 | let pos2 = list.getNodeValue(2)
14 | expect(pos3).toBe(120)
15 | expect(pos2).toBe(30)
16 | })
17 |
18 | })
19 |
20 | class Node {
21 | constructor(data) {
22 | this.data = data
23 | this.next = null
24 | }
25 | }
26 |
27 | class SinglyLinkedList {
28 | insert(data) {
29 | let newNode = new Node(data)
30 | if (!this.head) {
31 | this.head = newNode
32 | return this.head
33 | }
34 | let current = this.head
35 | while (current.next) {
36 | current = current.next
37 | }
38 | current.next = newNode
39 | return current
40 | }
41 |
42 | getNodeValue(positionFromTail) {
43 | let head = this.head
44 | let hash = {}; let length = 0; let count = -1;
45 |
46 | while (head) {
47 | count++
48 | hash[count] = head.data
49 | length = Math.max(length, count)
50 | head = head.next
51 | }
52 |
53 | return hash[length - positionFromTail]
54 | }
55 | }
--------------------------------------------------------------------------------
/hackerRank/linkedList/insertAtHead.js:
--------------------------------------------------------------------------------
1 | /* https://www.hackerrank.com/challenges/insert-a-node-at-the-head-of-a-linked-list/problem
2 |
3 | complexity analysis
4 | 0(1) - space
5 | 0(1) - time
6 | */
7 |
8 |
9 | function insertNodeAtHead(head, data) {
10 | if(head === null) return new SinglyLinkedListNode(data)
11 |
12 | let llist = new SinglyLinkedListNode(data)
13 | llist.next = head
14 | return llist
15 | }
16 |
--------------------------------------------------------------------------------
/hackerRank/linkedList/insertAtHead.test.js:
--------------------------------------------------------------------------------
1 | //Run test: npm test ./hackerRank/linkedList/insertAtHead.test.js
2 |
3 |
4 | describe('#insertAtHead', () => {
5 | it('inserts node at head of linked list', () => {
6 | const newNode = new SinglyLinkedList()
7 | newNode.insertAtHead(10)
8 | const oldHead = newNode.head
9 | newNode.insertAtHead(20)
10 | expect(newNode.head.data).toBe(20)
11 | expect(oldHead.data).toBe(10)
12 | expect(newNode.size).toBe(2)
13 | })
14 | })
15 |
16 | const SinglyLinkedListNode = class {
17 | constructor(nodeData) {
18 | this.data = nodeData;
19 | this.next = null;
20 | }
21 | };
22 |
23 | const SinglyLinkedList = class {
24 | constructor() {
25 | this.head = null;
26 | this.size = 0
27 | }
28 |
29 | insertAtHead(element) {
30 | const newNode = new SinglyLinkedListNode(element)
31 | newNode.next = this.head
32 | this.head = newNode
33 | this.size++
34 | }
35 | };
--------------------------------------------------------------------------------
/hackerRank/linkedList/insertAtTail.js:
--------------------------------------------------------------------------------
1 | /* https://www.hackerrank.com/challenges/insert-a-node-at-the-tail-of-a-linked-list/problem
2 |
3 | complexity analysis
4 | 0(n) - time | 0(1) - space
5 |
6 | * For your reference:
7 | *
8 | * SinglyLinkedListNode {
9 | * int data;
10 | * SinglyLinkedListNode next;
11 | * }
12 | *
13 | */
14 |
15 | function insertAtTail(head) {
16 | let newNode = new SinglyLinkedListNode(head)
17 |
18 | if (!head) {
19 | head = newNode
20 | return head
21 | }
22 |
23 | let current = head
24 |
25 | while (current.next) {
26 | current = current.next
27 | }
28 |
29 | current.next = newNode
30 | return current
31 | }
--------------------------------------------------------------------------------
/hackerRank/linkedList/insertAtTail.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | Run test: npm test ./hackerRank/linkedList/insertAtTail.test.js
3 | */
4 |
5 | describe('insert node at tail', () => {
6 | it('inserts new node at the tail of linked list', () => {
7 | let newNode = new singlyLinkedList()
8 | newNode.insertAtTail(10)
9 | newNode.insertAtTail(20)
10 | expect(newNode.head.next.next.data).toBe(20)
11 | })
12 | })
13 |
14 | class Node{
15 | constructor(data){
16 | this.data = data
17 | this.next = null
18 | }
19 | }
20 |
21 | class singlyLinkedList{
22 | constructor(){
23 | this.head = new Node('head')
24 | }
25 |
26 | insertAtTail(data){
27 | let newNode = new Node(data)
28 | let currData = this.head
29 |
30 | while(currData !== null){
31 | if (currData.next === null){
32 | currData.next = newNode
33 | newNode.next = null
34 | }
35 | currData = currData.next
36 | }
37 | return 2
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/hackerRank/linkedList/insertIntoDoublyLinkedList.js:
--------------------------------------------------------------------------------
1 | //www.hackerrank.com/challenges/insert-a-node-into-a-sorted-doubly-linked-list/problem?isFullScreen=true
2 | // test: npm test ./hackerRank/linkedList/insertIntoDoublyLinkedList.test.js
3 | // 0(1) - space | 0(n) - time
4 | /*
5 | * Complete the 'sortedInsert' function below.
6 | *
7 | * The function is expected to return an INTEGER_DOUBLY_LINKED_LIST.
8 | * The function accepts following parameters:
9 | * 1. INTEGER_DOUBLY_LINKED_LIST llist
10 | * 2. INTEGER data
11 | */
12 |
13 | /*
14 | * For your reference:
15 | *
16 | * DoublyLinkedListNode {
17 | * int data;
18 | * DoublyLinkedListNode next;
19 | * DoublyLinkedListNode prev;
20 | * }
21 | *
22 | */
23 |
24 | function sortedInsert(llist, data) {
25 | // Write your code here
26 | let list = llist
27 | let newNode = new DoublyLinkedListNode(data)
28 |
29 | if (!list) {
30 | list = newNode
31 | return list
32 | }
33 |
34 | if (data < list.data) {
35 | list.prev = newNode
36 | newNode.next = list
37 | return newNode
38 | }
39 |
40 | while (list) {
41 | if (data >= list.data && list.next === null) {
42 | list.next = newNode
43 | newNode.prev = list
44 | return llist;
45 | }
46 | if (list.next.data >= data) {
47 | newNode.next = list.next
48 | newNode.prev = list
49 | list.next = newNode
50 | list.next.prev = newNode
51 | return llist
52 | }
53 |
54 | list = list.next
55 |
56 | }
57 | return llist
58 | }
59 |
--------------------------------------------------------------------------------
/hackerRank/linkedList/insertNodeAtAGivenPos.js:
--------------------------------------------------------------------------------
1 | /* https://www.hackerrank.com/challenges/insert-a-node-at-a-specific-position-in-a-linked-list/problem?isFullScreen=true
2 |
3 | 0(n) - time | 0(1) - space
4 |
5 | * Complete the 'insertNodeAtPosition' function below.
6 | *
7 | * The function is expected to return an INTEGER_SINGLY_LINKED_LIST.
8 | * The function accepts following parameters:
9 | * 1. INTEGER_SINGLY_LINKED_LIST llist
10 | * 2. INTEGER data
11 | * 3. INTEGER position
12 | */
13 |
14 | /*
15 | * For your reference:
16 | *
17 | * SinglyLinkedListNode {
18 | * int data;
19 | * SinglyLinkedListNode next;
20 | * }
21 | *
22 | */
23 |
24 | function insertNodeAtPosition(llist, data, position) {
25 | // Write your code here
26 | let newNode = new SinglyLinkedListNode(data)
27 |
28 | if (position === 0) {
29 | llist = newNode
30 | return llist
31 | }
32 |
33 | let current = llist
34 | let count = 0
35 |
36 | while (current) {
37 | if (count === position - 1) {
38 | let posHolder = current.next
39 | current.next = newNode
40 | newNode.next = posHolder
41 | }
42 | current = current.next
43 | count++
44 | }
45 | return llist
46 | }
47 |
--------------------------------------------------------------------------------
/hackerRank/linkedList/insertNodeAtAGivenPos.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | Run test: npm test ./hackerRank/linkedList/insertNodeAtAGivenPos.test.js
3 | */
4 |
5 | describe('Insert node at a given position', () => {
6 | it('inserts node at a given position', () => {
7 | let node = new singlyLinkedList()
8 | node.insert(10)
9 | node.insert(20)
10 | let givenPos = node.insertAtPos(30, 1)
11 | expect(givenPos.next.data).toBe(30)
12 | })
13 | })
14 |
15 | class Node {
16 | constructor(data) {
17 | this.data = data
18 | this.next = null
19 | }
20 | }
21 |
22 | class singlyLinkedList {
23 | insert(data) {
24 | let newNode = new Node(data)
25 |
26 | if (!this.head) {
27 | this.head = newNode
28 | return this.head
29 | }
30 |
31 | let current = this.head
32 |
33 | while (current.next) {
34 | current = current.next
35 | }
36 |
37 | current.next = newNode
38 | return current
39 | }
40 | insertAtPos(data, position) {
41 | let newNode = new Node(data)
42 |
43 | if (position === 0) {
44 | this.head = newNode
45 | return this.head
46 | }
47 |
48 | let current = this.head
49 | let count = 0
50 |
51 | while (current) {
52 | if (count === position - 1) {
53 | let holder = current.next
54 | current.next = newNode
55 | newNode.next = holder
56 | }
57 | current = current.next
58 | count++
59 | }
60 | return this.head
61 | }
62 | }
--------------------------------------------------------------------------------
/hackerRank/linkedList/mergePoint.js:
--------------------------------------------------------------------------------
1 | //https://www.hackerrank.com/challenges/find-the-merge-point-of-two-joined-linked-lists/problem
2 | // 0(mn) - time | 0(1) - space
3 | // tests: pending
4 |
5 | /*
6 | Find merge point of two linked lists
7 | Note that the head may be 'null' for the empty list.
8 | Node is defined as
9 | var Node = function(data) {
10 | this.data = data;
11 | this.next = null;
12 | }
13 | */
14 |
15 | // This is a "method-only" submission.
16 | // You only need to complete this method.
17 |
18 | function findMergeNode(headA, headB) {
19 | let m = length(headA)
20 | let n = length(headB)
21 | let list = headB
22 |
23 |
24 | for (let i = 0; i < m; i++) {
25 | headB = list
26 | for (let j = 0; j < n; j++) {
27 | if (headA === headB) {
28 | return headA.data
29 | } else {
30 |
31 | headB = headB.next
32 |
33 | }
34 | }
35 | headA = headA.next
36 | }
37 | }
38 |
39 | function length(head) {
40 | let list = head
41 | let len = 0
42 | while (list) {
43 | len++
44 | list = list.next
45 | }
46 | return len
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/hackerRank/linkedList/mergeSortedList.js:
--------------------------------------------------------------------------------
1 | // DAY 9 OF A 10-DAY LINKED LIST CHALLENGE
2 |
3 | // this question has already been solved during a leetcode practice.
4 | // Find test here: npm test ./leetcode/linked-list/mergeLinkedList.test.js
5 | // 0(n) - t | 0(n) - space
6 | // https://www.hackerrank.com/challenges/merge-two-sorted-linked-lists/problem
7 |
8 | // Complete the mergeLists function below.
9 |
10 | /*
11 | * For your reference:
12 | *
13 | * SinglyLinkedListNode {
14 | * int data;
15 | * SinglyLinkedListNode next;
16 | * }
17 | *
18 | */
19 | function mergeLists(head1, head2) {
20 | let dummyNode = new SinglyLinkedListNode(0)
21 | let merged = dummyNode
22 |
23 | while (true) {
24 | if (!head1) {
25 | merged.next = head2;
26 | break;
27 | }
28 | if (!head2) {
29 | merged.next = head1;
30 | break;
31 | }
32 | if (head1.data <= head2.data) {
33 | merged.next = head1
34 | head1 = head1.next
35 | } else {
36 | merged.next = head2
37 | head2 = head2.next
38 | }
39 | merged = merged.next
40 | }
41 | return dummyNode.next
42 | }
43 |
--------------------------------------------------------------------------------
/hackerRank/linkedList/printInReverse.js:
--------------------------------------------------------------------------------
1 | /* DAY 6 & 7 OF A 10-DAY LINKED LIST CHALLENGE WITH SODIQ AYILARA MD
2 |
3 | https://www.hackerrank.com/challenges/print-the-elements-of-a-linked-list-in-reverse/problem?isFullScreen=true
4 |
5 | Test: npm test ./hackerRank/linkedList/printInReverse.test.js
6 |
7 | 0(n) - time | 0(1) - space
8 | */
9 |
10 |
11 | /*
12 | * Complete the 'reversePrint' function below.
13 | *
14 | * The function accepts INTEGER_SINGLY_LINKED_LIST llist as parameter.
15 | */
16 |
17 | /*
18 | * For your reference:
19 | *
20 | * SinglyLinkedListNode {
21 | * int data;
22 | * SinglyLinkedListNode next;
23 | * }
24 | *
25 | */
26 |
27 | function reversePrint(llist) {
28 | if (llist) {
29 | reversePrint(llist.next)
30 | console.log(llist.data)
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/hackerRank/linkedList/printInReverse.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | TEST: npm test ./hackerRank/linkedList/printInReverse.test.js
3 | */
4 |
5 | describe('print in reverse', () => {
6 | it('prints the data values of a linked list in reverse', () => {
7 | const list = new SinglyLinkedList()
8 | list.insert(10)
9 | list.insert(20)
10 | list.insert(30)
11 | const reverse = list.reverse()
12 | expect(reverse.data).toBe(30)
13 | expect(reverse.next.data).toBe(20)
14 | expect(reverse.next.next.data).toBe(10)
15 | expect(reverse.next.next.next).toBe(null)
16 | })
17 | })
18 |
19 | class Node{
20 | constructor(data){
21 | this.data = data
22 | this.next = null
23 | }
24 | }
25 |
26 | class SinglyLinkedList{
27 | insert(data){
28 | let newNode = new Node(data)
29 | if(!this.head){
30 | this.head = newNode
31 | return this.head
32 | }
33 | let current = this.head
34 | while(current.next){
35 | current = current.next
36 | }
37 | current.next = newNode
38 | return current
39 | }
40 |
41 | reverse(){
42 | if(this.head){
43 | let current = this.head
44 | let prev = null
45 |
46 | while(current){
47 | let nxt = current.next
48 | current.next = prev
49 | prev = current
50 | current = nxt
51 | }
52 | return prev
53 | }
54 |
55 | while(prev){
56 | console.log(prev.data)
57 | prev = prev.next
58 | }
59 | }
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/hackerRank/linkedList/printLinkedList.js:
--------------------------------------------------------------------------------
1 | /* https://www.hackerrank.com/challenges/print-the-elements-of-a-linked-list/problem?isFullScreen=true
2 |
3 | complexity anaysis
4 | 0(n) - time
5 | 0(1) - space
6 | */
7 |
8 | function printLinkedList(head) {
9 | let currEl = head
10 |
11 | while(currEl !== null){
12 | console.log(currEl.data)
13 | currEl = currEl.next
14 |
15 | }
16 | }
--------------------------------------------------------------------------------
/hackerRank/linkedList/printLinkedList.test.js:
--------------------------------------------------------------------------------
1 | //Run test: npm test ./hackerRank/linkedList/printLinkedList.test.js
2 |
3 |
4 | describe('print the element of a linked list', () => {
5 | it('returns the el in a list', () => {
6 | let list = new LList()
7 | list.insert(2, 'head')
8 | list.insert(16, 2)
9 | list.insert(18, 6)
10 | expect(list.size).toBe(3)
11 | expect(list.head.next.element).toBe(2)
12 | expect(list.display()).toStrictEqual([16, 18])
13 | })
14 | })
15 |
16 | class Node {
17 | constructor(element) {
18 | this.element = element
19 | this.next = null
20 | }
21 | }
22 |
23 | class LList {
24 | constructor() {
25 | this.head = new Node('head')
26 | this.size = 0
27 | }
28 |
29 | find(item) {
30 | let currNode = this.head
31 | while (currNode !== item && currNode.next !== null) {
32 | currNode = currNode.next
33 | }
34 | return currNode
35 | }
36 |
37 | // this function assumes newEl is inserted after item in a linked list
38 | insert(newEl, item) {
39 | let newNode = new Node(newEl)
40 | let current = this.find(item)
41 | if (current.next) {
42 | newNode.next = current.next
43 | } else {
44 | newNode.next = null
45 | }
46 | current.next = newNode
47 | this.size++
48 | }
49 |
50 | display() {
51 | let currNode = this.head.next
52 | let values = []
53 | while (currNode !== null && this.size > 1) {
54 | console.log(currNode.next.element)
55 | values.push(currNode.next.element)
56 | currNode = currNode.next
57 | this.size--
58 | }
59 | return values
60 | }
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/hackerRank/linkedList/reverseDoublyLinkedList.js:
--------------------------------------------------------------------------------
1 | //https://www.hackerrank.com/challenges/reverse-a-doubly-linked-list/problem?isFullScreen=true
2 | // Test: npm test ./hackerRank/linkedList/reverseDoublyLinkedlist.test.js
3 | // 0(n) - time | 0(n) - space
4 |
5 |
6 | /*
7 | * Complete the 'reverse' function below.
8 | *
9 | * The function is expected to return an INTEGER_DOUBLY_LINKED_LIST.
10 | * The function accepts INTEGER_DOUBLY_LINKED_LIST llist as parameter.
11 | */
12 |
13 | /*
14 | * For your reference:
15 | *
16 | * DoublyLinkedListNode {
17 | * int data;
18 | * DoublyLinkedListNode next;
19 | * DoublyLinkedListNode prev;
20 | * }
21 | *
22 | */
23 |
24 | function reverse(llist) {
25 | // Write your code here
26 | let current = llist
27 | if (!current) return;
28 |
29 | let temp = null
30 |
31 | while (current) {
32 | let ptr2 = current.next
33 | current.next = temp
34 | current.prev = ptr2
35 | temp = current
36 | current = ptr2
37 | }
38 |
39 | if (temp) {
40 | llist = temp
41 | }
42 |
43 | return llist
44 |
45 | }
--------------------------------------------------------------------------------
/hackerRank/linkedList/reverseDoublyLinkedList.test.js:
--------------------------------------------------------------------------------
1 | //https://www.hackerrank.com/challenges/reverse-a-doubly-linked-list/problem?isFullScreen=true
2 | // Test: npm test ./hackerRank/linkedList/reverseDoublyLinkedlist.test.js
3 | // 0(n) - time | 0(n) - space
4 |
5 | describe('reverse doubly linked list', () => {
6 | it('reverses a doubly linked list in place', () => {
7 | const list = new DoublyLinkedList()
8 | list.insert(10)
9 | list.insert(20)
10 | list.insert(30)
11 | let listReverse = list.reverse()
12 | expect(listReverse.data).toBe(30)
13 | expect(listReverse.prev).toBe(null)
14 | expect(listReverse.next.prev.data).toBe(30)
15 | })
16 | })
17 |
18 | class Node {
19 | constructor(data) {
20 | this.data = data;
21 | this.next = null;
22 | this.prev = null;
23 | }
24 | }
25 |
26 | class DoublyLinkedList {
27 | insert(data) {
28 | let newNode = new Node(data)
29 | if (!this.head) {
30 | this.head = newNode
31 | return this.head
32 | }
33 |
34 | let current = this.head
35 |
36 | while (current.next) {
37 | current = current.next
38 | }
39 |
40 | current.next = newNode
41 | return this.head
42 | }
43 |
44 | reverse() {
45 | if (!this.head) return
46 |
47 | let prev = null
48 | let current = this.head
49 |
50 | while (current) {
51 | let nxt = current.next
52 | current.next = prev
53 | current.prev = nxt
54 | prev = current
55 | current = nxt
56 | }
57 | return prev
58 | }
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/hackerRank/readme.md:
--------------------------------------------------------------------------------
1 | ## Index of solution
2 |
3 | | Index | Topic | Link |
4 | | ----- | -------- | --------------- |
5 | | 1. | [Linked List](https://www.hackerrank.com/domains/data-structures?filters%5Bsubdomains%5D%5B%5D=linked-lists) | [Link](https://github.com/blossom-babs/Data-structures-and-algorithm/blob/main/hackerRank/linkedList) |
6 | | 2. | [Arrays](https://www.hackerrank.com/domains/data-structures?filters%5Bsubdomains%5D%5B%5D=arrays) | [Link](https://github.com/blossom-babs/Data-structures-and-algorithm/blob/main/hackerRank/Arrays) |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | function* generatorFunction() {
2 | index = 0
3 | while (true) {
4 | yield index
5 | index += 1
6 | }
7 | }
8 |
9 | let gen = generatorFunction()
10 |
11 |
12 | for (let value of gen) {
13 | console.log(value)
14 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/arithmetic-progression.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | https://leetcode.com/problems/can-make-arithmetic-progression-from-sequence/
3 |
4 | test: npm test ./leetcode/easy/arithmetic-progression.test.js
5 |
6 | complexity analysis
7 | 0(1) space
8 | 0(n) time
9 | */
10 |
11 | const arithmeticProgression = (arr) => {
12 | arr = arr.sort((a, b) => a - b);
13 | let diff = arr[0] - arr[1];
14 | for (let i = 1; i < arr.length - 1; i++) {
15 | if (arr[i] - arr[i + 1] !== diff) {
16 | return false;
17 | }
18 | }
19 | return true;
20 | };
21 |
22 | describe("can array make an arithmetic progression", () => {
23 | it("returns true", () => {
24 | expect(arithmeticProgression([5, 3, 1])).toBe(true);
25 | expect(arithmeticProgression([1, 200])).toBe(true);
26 | expect(arithmeticProgression([-1, -2, -3])).toBe(true);
27 | expect(arithmeticProgression([1, 1, 1])).toBe(true);
28 | });
29 | it("returns false", () => {
30 | expect(arithmeticProgression([1, 2, 4])).toBe(false);
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/leetcode/javascript/easy/balancedBinaryTree.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/balanced-binary-tree/
2 | // TEST: npm test ./leetcode/easy/balancedBinaryTree.test.js
3 | //0(1) - space | 0(n) - time
4 |
5 | const BST = require("./BST-testcase.test");
6 |
7 | describe('#Balanced Binary tree', () => {
8 | let bst;
9 |
10 | beforeEach(() => {
11 | bst = new BST()
12 | })
13 |
14 | it('returns true if tree is balanced', () => {
15 | bst.insert(bst.root, 6); bst.insert(bst.root, 3);
16 | bst.insert(bst.root, 7); bst.insert(bst.root, 2);
17 | bst.insert(bst.root, 5);
18 | expect(balancedBinaryTree(bst.root)).toBe(true)
19 | })
20 |
21 |
22 | it('returns false if tree is not balanced', () => {
23 | bst.insert(bst.root, 6); bst.insert(bst.root, 5);
24 | bst.insert(bst.root, 7); bst.insert(bst.root, 4);
25 | bst.insert(bst.root, 8); bst.insert(bst.root, 3);
26 | expect(balancedBinaryTree(bst.root)).toBe(false)
27 | })
28 |
29 | it('returns false if tree is not balanced', () => {
30 | expect(balancedBinaryTree(bst.root)).toBe(true)
31 | })
32 | })
33 |
34 | const balancedBinaryTree = root => {
35 | if(!root) return true
36 |
37 | let output = true
38 |
39 | const dfs = root => {
40 | if(!root) return 0
41 |
42 | const left = dfs(root.left)
43 | const right = dfs(root.right)
44 |
45 | if(Math.abs(left - right) > 1) output = false
46 |
47 | return Math.max(left, right) + 1
48 | }
49 | dfs(root)
50 | return output
51 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/bestTimeToBuyAndSellStock.test.js:
--------------------------------------------------------------------------------
1 | /* https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
2 |
3 | Run test: npm test ./leetcode/easy/bestTimeToBuyAndSellStock.test.js
4 |
5 | 0(n) - time | 0(1) - space
6 | */
7 |
8 | describe('BEST TIME TO BUY AND SELL STOCK', () => {
9 | it('buys low, sells high and returns the maximum profit made', () => {
10 | expect(maxProfit([7, 1, 5, 3, 6])).toBe(5)
11 | expect(maxProfit([7, 6, 4, 3, 1])).toBe(0)
12 | expect(maxProfit([2, 1, 2, 1, 0, 1, 2])).toBe(2)
13 | })
14 | })
15 |
16 | const maxProfit = prices => {
17 | let maxProfit = 0
18 | let left = 0
19 | let right = 1
20 |
21 | while (right < prices.length) {
22 | let profit = prices[right] - prices[left]
23 |
24 | if (profit < 0) {
25 | left++
26 | } else {
27 | right++
28 | }
29 |
30 | maxProfit = Math.max(maxProfit, profit)
31 | }
32 | return maxProfit
33 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/binarySearch.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/binary-search/
2 | //Test: npm test ./leetcode/easy/binarySearch.test.js
3 | //0(log n) - time | 0(1) - space
4 |
5 | describe('#binary search', () => {
6 | it('returns the index of a given target', () => {
7 | expect(binarySearch([1, 0, 3, 5, 9, 12], 9)).toBe(4)
8 | expect(binarySearch([1, 0, 3, 5, 9, 12], 2)).toBe(-1)
9 | expect(binarySearch([1], 2)).toBe(-1)
10 | })
11 | })
12 |
13 |
14 | const binarySearch = (nums, target) => {
15 | let lower = 0
16 | let upper = nums.length - 1
17 |
18 | while (lower <= upper) {
19 | let mid = lower + Math.floor((upper - lower) / 2)
20 |
21 | if (target === nums[mid]) {
22 | return mid
23 | }
24 |
25 | if (target > nums[mid]) {
26 | lower = mid + 1
27 | } else {
28 | upper = mid - 1
29 | }
30 | }
31 |
32 | return -1
33 | };
--------------------------------------------------------------------------------
/leetcode/javascript/easy/contains-duplicates.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/contains-duplicate/
2 | //Test: npm test ./leetcode/easy/contains-duplicates.test.js
3 |
4 |
5 | describe('check if arr of integers contains duplicates', () => {
6 | it('returns true if duplicate value is found', () => {
7 | expect(containsDuplicate([1, 2, 3, 1])).toBe(true)
8 | expect(containsDuplicateTwo([1, 1, 1, 3, 3, 4, 3, 2, 4, 2])).toBe(true)
9 | expect(containsDuplicateThree([-1, -1, 1, 2, 3, 4, 5, 5, 1])).toBe(true)
10 | })
11 | it('returns false if duplicate not found', () => {
12 | expect(containsDuplicate([1, 2, 3, 4])).toBe(false)
13 | expect(containsDuplicateTwo([3, 4])).toBe(false)
14 | expect(containsDuplicateThree([])).toBe(false)
15 | })
16 | })
17 |
18 | // April 2022
19 | // 0(n log n) - time | 0(log n) - space (quick sort)
20 | const containsDuplicate = nums => {
21 | nums = nums.sort((a, b) => a - b)
22 |
23 | for (let i = 0; i < nums.length; i++) {
24 | if (nums[i] === nums[i + 1]) return true
25 | }
26 |
27 | return false
28 | }
29 |
30 | //0(n) - time | 0(n) - space
31 | const containsDuplicateTwo = nums => {
32 | let numsTable = {}
33 | let i = 0
34 |
35 | while (i < nums.length) {
36 | if ((nums[i] in numsTable)) {
37 | return true
38 | }
39 | numsTable[nums[i]] = i
40 | i++
41 | }
42 | return false
43 | }
44 |
45 | // May 20 2022 | 4am wat
46 | // 0(n) - time | 0(n) - space
47 |
48 | const containsDuplicateThree = nums => {
49 | let hash = {}
50 |
51 | for (const num of nums) {
52 | if (hash[num]) return true
53 | hash[num] = 1
54 | }
55 | return false
56 | }
57 |
--------------------------------------------------------------------------------
/leetcode/javascript/easy/contains-dupsII.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/contains-duplicate-ii/
2 | //Test: npm test ./leetcode/easy/contains-dupsII.test.js
3 |
4 | describe('#contains duplicates II', () => {
5 | it('returns true if array contains duplicates and difference of duplicates(index) is less than integer k', () => {
6 | expect(containsNearbyDuplicates([3], 3)).toBe(false)
7 | expect(containsNearbyDuplicates([], 13)).toBe(false)
8 | expect(containsNearbyDuplicates([1, 2, 3, 1], 3)).toBe(true)
9 | expect(containsNearbyDuplicates([1,0,1,1,1], 1)).toBe(true)
10 | expect(containsNearbyDuplicates([1,2,3,1,2,3], 2)).toBe(false)
11 | })
12 | })
13 |
14 |
15 | // 0(n) - time | 0(n) - space
16 | containsNearbyDuplicates = (nums, k) => {
17 | let hash = {}
18 |
19 | for (let i = 0; i < nums.length; i++) {
20 | let num = nums[i]
21 |
22 | if (hash.hasOwnProperty(num)) {
23 | let diff = Math.abs(hash[num] - i)
24 | if (diff <= k) return true
25 | }
26 |
27 | hash[num] = i
28 |
29 | }
30 |
31 | return false
32 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/diameterBinaryTree.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/diameter-of-binary-tree/
2 | // TEST: npm test ./leetcode/easy/diameterBinaryTree.test.js
3 | //0(1) - space | 0(n) - time
4 |
5 | const BST = require("./BST-testcase.test");
6 |
7 | describe('Diamter of a binary tree', () => {
8 | let bst;
9 |
10 | beforeEach(() => {
11 | bst = new BST()
12 | })
13 |
14 | it('returns the diamter of a binary tree', () => {
15 | bst.insert(bst.root, 6); bst.insert(bst.root, 3);
16 | bst.insert(bst.root, 7); bst.insert(bst.root, 2);
17 | bst.insert(bst.root, 5);
18 | expect(diameterOfABinaryTree(bst.root)).toBe(3)
19 | })
20 |
21 | it('returns the diamter of a binary tree', () => {
22 | bst.insert(bst.root, 1); bst.insert(bst.root, 2);
23 | expect(diameterOfABinaryTree(bst.root)).toBe(1)
24 | })
25 |
26 | it('returns the diamter of a binary tree', () => {
27 | expect(diameterOfABinaryTree(bst.root)).toBe(0)
28 | })
29 | })
30 |
31 | const diameterOfABinaryTree = root => {
32 | let res = 0
33 |
34 | const dfs = root => {
35 | if (!root) return -1
36 |
37 | const left = dfs(root.left)
38 | const right = dfs(root.right)
39 |
40 | res = Math.max(res, 2 + left + right)
41 |
42 | return Math.max(left, right) + 1
43 | }
44 | dfs(root)
45 | return res
46 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/firstPalindrome.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/valid-palindrome/
2 | // Test: npm test ./leetcode/easy/firstPalindrome.test.js
3 | //0(n * k) - time | 0(1) - space
4 |
5 | describe('#first palindrome in an array', () => {
6 | it('returns the first palindrome in an array of strings', () => {
7 | expect(firstPalindrome(["abc","car","ada","racecar","cool"])).toBe('ada')
8 | expect(firstPalindrome(["notapalindrome","racecar"])).toBe('racecar')
9 | expect(firstPalindrome([["def","ghi"]])).toBe('')
10 | })
11 | })
12 |
13 | const firstPalindrome = arr => {
14 | for (const word of arr) {
15 | if (validPalindrome(word)) return word
16 | }
17 |
18 | return ''
19 | }
20 |
21 | const validPalindrome = s => {
22 | let l = 0
23 | let r = s.length - 1
24 | while (l < r) {
25 | if (s[l].toLowerCase() !== s[r].toLowerCase()) return false
26 | l++
27 | r--
28 | }
29 | return true
30 | }
31 |
32 |
33 |
--------------------------------------------------------------------------------
/leetcode/javascript/easy/group-anagrams.test.js:
--------------------------------------------------------------------------------
1 | /* https://leetcode.com/problems/group-anagrams/
2 |
3 | Test: npm test ./leetcode/arrays/group-anagrams.test.js
4 |
5 | 0(n) - space | 0(m * nlogn) - time
6 | */
7 |
8 | describe('Group Anagrams', () => {
9 | it('groups anagrams together', () => {
10 | expect(groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"])).toStrictEqual([["eat", "tea", "ate"], ["tan", "nat"], ["bat"]])
11 | expect(groupAnagrams([" "])).toStrictEqual([[" "]])
12 | expect(groupAnagrams(["a"])).toStrictEqual([["a"]])
13 | })
14 | })
15 |
16 | const groupAnagrams = strs => {
17 | let hash = {}
18 |
19 | for (let str of strs) {
20 | let sorted = str.split('').sort().join('')
21 |
22 | if (hash[sorted]) {
23 | hash[sorted].push(str)
24 | } else {
25 | hash[sorted] = [str]
26 | }
27 | }
28 |
29 | return Object.values(hash)
30 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/happyNum.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | https://leetcode.com/problems/happy-number/
3 |
4 | complexity analysis
5 | 0(n) - space (hashtable was used)
6 | 0(n) - time
7 | */
8 |
9 | describe('Happy numbers', () => {
10 | it('returns true if number is happy', () =>{
11 | expect(isHappy(7)).toBe(true)
12 | expect(isHappy(19)).toBe(true)
13 | expect(isHappy(1)).toBe(true)
14 | })
15 | it('returns false if number is not happy', () =>{
16 | expect(isHappy(2)).toBe(false)
17 | expect(isHappy(0)).toBe(false)
18 | expect(isHappy(-1)).toBe(false)
19 | })
20 | })
21 |
22 | const isHappy = n => {
23 | let numbers = {}
24 |
25 | while (!(n in numbers)) {
26 | if (n === 1) return true
27 | numbers[n] = n
28 |
29 | n = ('' + n).split('').map(num => parseInt(num * num))
30 | .reduce((curr, prev) => curr + prev)
31 | }
32 | return false
33 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/implementStackUsingQueues.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/implement-stack-using-stacks/submissions/
2 | // Test: npm test ./leetcode/easy/implementStackUsingQueues.test.js
3 |
4 | describe('Implement stack using queue', () => {
5 | let obk;
6 |
7 | beforeEach(() => {
8 | obj = new MyStack()
9 | obj.push(7); obj.push(8); obj.push(9)
10 | })
11 |
12 | it('adds element to the end of stack', () => {
13 | expect(obj.stack).toStrictEqual([7, 8,9])
14 | })
15 |
16 | it('removed element from the end of stack', () => {
17 | expect(obj.pop()).toStrictEqual(9)
18 | })
19 |
20 | it('returns the last element in the stack', () => {
21 | expect(obj.top()).toStrictEqual(9)
22 | })
23 |
24 | it('returns false if the stack is empty', () => {
25 | expect(obj.empty()).toStrictEqual(false)
26 | })
27 | })
28 |
29 |
30 | class MyStack {
31 | constructor() {
32 | this.stack = []
33 | }
34 |
35 | // 0(1) - time && space
36 | push(x) {
37 | return this.stack[this.stack.length++] = x
38 | }
39 |
40 | // 0(n) - time | 0(1) - space
41 | pop() {
42 | for (let i = 0; i < this.stack.length - 1; i++) {
43 | this.stack.push(this.stack.shift())
44 | }
45 | return this.stack.shift()
46 | }
47 |
48 | // 0(1) - time | 0(1) - space
49 | top() {
50 | return this.stack[this.stack.length - 1]
51 | }
52 |
53 |
54 | empty() {
55 | return this.stack.length === 0
56 | }
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/leetcode/javascript/easy/invertBST.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/invert-binary-tree/
2 | // test: npm test ./leetcode/easy/invertBST.test.js
3 | // 0(h) - time | 0(1) - space
4 |
5 | describe('#invert tree', () => {
6 | let bst
7 | beforeEach(() => {
8 | bst = new BST()
9 | bst.insert(bst.root, 4)
10 | bst.insert(bst.root, 2); bst.insert(bst.root, 7);
11 | bst.insert(bst.root, 1); bst.insert(bst.root, 3)
12 | bst.insert(bst.root, 6); bst.insert(bst.root, 9)
13 | })
14 |
15 | it('expects tree to be inverted', () => {
16 | let invert = bst.invertTree(bst.root)
17 | expect(invert.left.data).toBe(7)
18 | })
19 |
20 | })
21 |
22 | class Node {
23 | constructor(data) {
24 | this.data = data
25 | this.left = this.right = null
26 | }
27 | }
28 |
29 | class BST {
30 | constructor() {
31 | this.root = null
32 | }
33 |
34 | insert(root, data) {
35 | let newNode = new Node(data)
36 | if (!root) {
37 | this.root = newNode
38 | return root
39 | }
40 |
41 | if (data < root.data) {
42 | if (!root.left) root.left = newNode
43 | else this.insert(root.left, data)
44 | } else {
45 | if (!root.right) root.right = newNode
46 | else this.insert(root.right, data)
47 | }
48 | }
49 |
50 | invertTree(root) {
51 | if (!root) return root
52 | let temp = root.left
53 | root.left = root.right
54 | root.right = temp
55 |
56 | this.invertTree(root.left)
57 | this.invertTree(root.right)
58 |
59 | return root
60 | }
61 | }
62 |
63 |
64 | const invertTree = (root) => {
65 | if (!root) return root
66 |
67 | let temp = root.left
68 | root.left = root.right
69 | root.right = temp
70 |
71 | invertTree(root.right)
72 | invertTree(root.left)
73 |
74 | return root
75 | };
--------------------------------------------------------------------------------
/leetcode/javascript/easy/isPalindrome.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/valid-palindrome/
2 | // Test: npm test ./leetcode/easy/isPalindrome.test.js
3 |
4 | describe('is valid palindrome', () => {
5 | it('returns true if phrase is a valid palindrome', () => {
6 | expect(validPalindrome("Don't nod")).toBe(true)
7 | expect(validPalindrome('I did, did I?')).toBe(true)
8 | expect(validPalindrome('Amore roma')).toBe(true)
9 | expect(validPalindrome('A man, a plan, a canal: Panama')).toBe(true)
10 | expect(validPalindrome(' ')).toBe(true)
11 | expect(validPalindrome('aba')).toBe(true)
12 | })
13 | it('returns false if phrase is not a valid palindrome', () => {
14 | expect(validPalindrome('race a car')).toBe(false)
15 | expect(validPalindrome('Good job')).toBe(false)
16 | })
17 | })
18 |
19 | // may 2022 | 0(n) - time | 0(1) - space
20 | const validPalindrome = s => {
21 | let l = 0
22 | let r = s.length - 1
23 |
24 | while (l < r) {
25 | if (isAlphaNum(s[l]) === false) {
26 | l++
27 | continue
28 | }
29 |
30 | if (isAlphaNum(s[r]) === false) {
31 | r--
32 | continue
33 | }
34 |
35 | if (s[l].toLowerCase() !== s[r].toLowerCase()) return false
36 | l++
37 | r--
38 | }
39 |
40 | return true
41 | }
42 |
43 | const isAlphaNum = str => {
44 | str = str.charCodeAt(0)
45 | return (str >= ('0').charCodeAt(0) && str <= ('9').charCodeAt(0) ||
46 | str >= ('a').charCodeAt(0) && str <= ('z').charCodeAt(0) ||
47 | str >= ('A').charCodeAt(0) && str <= ('Z').charCodeAt(0))
48 | }
49 |
50 | // April 2022
51 | // 0(n ^2) - time | 0(n) - space
52 | const isPalindrome = s => {
53 | s = s.replace(/[^a-zA-Z0-9]/g).toLowerCase()
54 | let left = 0
55 | let right = s.length - 1
56 |
57 | while (left < right) {
58 | if (s[left++] !== s[right--]) return false
59 | }
60 |
61 | return true
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/leetcode/javascript/easy/isValid.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/valid-parentheses/
2 | // Test: npm test ./leetcode/medium/isValid.test.js
3 | //0(n) - time | 0(n) - space
4 |
5 | describe('is valid parentheses', () => {
6 | it('expects closing bracket for open bracket', () => {
7 | expect(isValid('([)]')).toBe(false)
8 | expect(isValid('([])]')).toBe(false)
9 | expect(isValid('()[]{}')).toBe(true)
10 | })
11 | })
12 | const isValid = (s) => {
13 | let stack = []
14 |
15 | for (let el of s) {
16 | let prev = stack[stack.length - 1]
17 |
18 | if (prev === '(' && el === ')') {
19 | stack.pop()
20 | } else if (prev === '[' && el === ']') {
21 | stack.pop()
22 | } else if (prev === '{' && el === '}') {
23 | stack.pop()
24 | } else {
25 | stack.push(el)
26 | }
27 | }
28 |
29 | return stack.length === 0
30 | };
--------------------------------------------------------------------------------
/leetcode/javascript/easy/max-subarray.test.js:
--------------------------------------------------------------------------------
1 | /* https://leetcode.com/problems/maximum-subarray/
2 | Test: npm test ./leetcode/easy/max-subarray.test.js
3 | complexity analysis 0(n) - time | 0(1) -space
4 | */
5 |
6 | describe('maximum subarray', () => {
7 | it('returns sum of the largest sub array', () => {
8 | expect(maxSubArray([-2,1,-3,4,-1,2,1,-5,4])).toBe(6)
9 | expect(maxSubArray([5,4,-1,7,8])).toBe(23)
10 | expect(maxSubArray([1])).toBe(1)
11 | expect(maxSubArray([-1, -5, 0])).toBe(0)
12 | })
13 | })
14 |
15 | const maxSubArray = arr => {
16 | let maxSub = arr[0]
17 | let currSum = 0
18 |
19 | for(let num of arr){
20 | if (currSum < 0) currSum = 0
21 | currSum += num
22 | maxSub = Math.max(maxSub, currSum)
23 | }
24 | return maxSub
25 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/maxDiff.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/maximum-difference-between-increasing-elements/
2 | //Test: npm test ./leetcode/easy/maxDiff.test.js
3 | //0(n) - time | 0(1) - space
4 |
5 | describe('#maximum difference of subarray', () => {
6 | it('returns the maximum difference in a subarray', () => {
7 | expect(maximumDifference([7,1,5,4])).toBe(4)
8 | expect(maximumDifference([9,4,3,2])).toBe(-1)
9 | expect(maximumDifference([1,5,2,10])).toBe(9)
10 | expect(maximumDifference([1,5])).toBe(4)
11 | })
12 | })
13 |
14 | var maximumDifference = function(nums) {
15 | let l = 0
16 | let r = 1
17 | let max = 0
18 |
19 | while(r < nums.length){
20 | let diff = nums[r] - nums[l]
21 |
22 | if(diff < 0){
23 | l++
24 | } else{
25 | r++
26 | }
27 |
28 | max = Math.max(max, diff)
29 | }
30 |
31 | return max > 0 ? max : -1
32 | };
--------------------------------------------------------------------------------
/leetcode/javascript/easy/mergeLinkedList.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/merge-two-sorted-lists/
2 | // Test: npm test ./leetcode/linked-list/mergeLinkedList.test.js
3 | // 0(n) - time | 0(n) - space
4 |
5 | describe('merge two linked list', () => {
6 |
7 | let list, list1, list2
8 | beforeEach(() => {
9 | list = new SinglyLinkedList()
10 | list1 = new SinglyLinkedList()
11 | list2 = new SinglyLinkedList()
12 | })
13 |
14 | it('merge sorted linked list', () => {
15 | list1.insert(10)
16 | list1.insert(20)
17 | list1.insert(50)
18 | list1.insert(80)
19 |
20 | list2.insert(10)
21 | list2.insert(20)
22 | list2.insert(30)
23 |
24 | let mergeNodes = list.merge(list1, list2)
25 | expect(mergeNodes.next.next.data).toBe(20)
26 |
27 | })
28 | })
29 |
30 | class Node {
31 | constructor(data) {
32 | this.data = data
33 | this.next = null
34 | }
35 | }
36 |
37 | class SinglyLinkedList {
38 | insert(data) {
39 | let newNode = new Node(data)
40 | if (!this.head) {
41 | this.head = newNode
42 | return this.head
43 | }
44 |
45 | let current = this.head
46 |
47 | while (current.next) {
48 | current = current.next
49 | }
50 | current.next = newNode
51 | return current
52 | }
53 |
54 | merge(list1, list2) {
55 | let head1 = list1.head
56 | let head2 = list2.head
57 |
58 | let dummyNode = new Node(0)
59 | let tail = dummyNode
60 |
61 | while (true) {
62 | if (!head1) {
63 | tail.next = head2
64 | break;
65 | }
66 | if (!head2) {
67 | tail.next = head1
68 | break
69 | }
70 | if (head1.data <= head2.data) {
71 | tail.next = head1
72 | head1 = head1.next
73 | } else {
74 | tail.next = head2
75 | head2 = head2.next
76 | }
77 |
78 | tail = tail.next
79 | }
80 | return dummyNode.next
81 | }
82 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/minStack.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/min-stack/
2 | // Test: npm test ./leetcode/easy/minStack.test.js
3 | // 0(1) - time | 0(n) - space
4 |
5 | describe('#min stack', () => {
6 | let minStack;
7 |
8 | beforeEach(() => {
9 | minStack = new MinStack();
10 | minStack.push(-2);
11 | minStack.push(0);
12 | minStack.push(-3);
13 | })
14 |
15 | it('PUSH element to the stack', () => {
16 | expect(minStack.stack).toStrictEqual([[-2, -2], [0, -2], [-3, -3]])
17 | })
18 |
19 | it('POP element from the stack', () => {
20 | minStack.pop()
21 | expect(minStack.stack).toStrictEqual([[-2, -2], [0, -2]])
22 | })
23 |
24 | it('returns element at the TOP of the stack', () => {
25 | let top = minStack.top()
26 | expect(top).toBe(-3)
27 | })
28 |
29 | it('returns the MINIMUM value in the stack in constant time', () => {
30 | let min = minStack.getMin()
31 | expect(min).toBe(-3)
32 | })
33 | })
34 |
35 | class MinStack {
36 | constructor() {
37 | this.stack = []
38 | }
39 |
40 | push(val) {
41 | let min = Math.min(val, this.getMin())
42 | this.stack[this.stack.length++] = [val, min]
43 | }
44 |
45 | pop() {
46 | this.stack.pop()
47 | }
48 |
49 | top() {
50 | return this.peek()[0]
51 | }
52 |
53 | getMin() {
54 | return this.peek()[1] ?? Infinity
55 | }
56 |
57 | peek() {
58 | return this.stack[this.stack.length - 1] || 0
59 | }
60 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/palindromeNum.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/palindrome-number/
2 | // test: npm test ./leetcode/easy/palindromeNum.test.js
3 |
4 | // FOLLOW UP: can you do it without converting the num to a string
5 |
6 | describe('Palindrome number', () => {
7 | it('returns true if int is a palindrome', () => {
8 | expect(isPalindrome(121)).toBe(true)
9 | expect(isPalindrome(0)).toBe(true)
10 | })
11 | it('returns false if int is not a palindrome', () => {
12 | expect(isPalindrome(182)).toBe(false)
13 | expect(isPalindrome(-121)).toBe(false)
14 | })
15 | })
16 |
17 | const isPalindrome = num => {
18 | if(num < 0) return false
19 | if(num === 0) return true
20 |
21 | let reversed = ''
22 | let newNum = num
23 | let digits = 0
24 |
25 | while(newNum){
26 | digits = newNum % 10
27 | newNum = Math.round(newNum / 10)
28 | reversed += digits
29 | }
30 |
31 | return parseInt(reversed) === num
32 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/product-sign.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | https://leetcode.com/problems/sign-of-the-product-of-an-array/
3 |
4 | Complexity analysis
5 | 0(n) - time
6 | 0(1) - space
7 | */
8 |
9 | const signFunc = (x) => {
10 | if (x > 0) {
11 | return 1;
12 | } else if (x < 0) {
13 | return -1;
14 | } else {
15 | return 0;
16 | }
17 | };
18 |
19 | const arraySign = (nums) => {
20 | let product = 1;
21 |
22 | for (let i = 0; i < nums.length; i++) {
23 | product *= nums[i];
24 | }
25 |
26 | return signFunc(product);
27 | };
28 |
29 | describe("sign of the product of an array", () => {
30 | it("returns 0 if product is 0", () => {
31 | expect(arraySign([1, 5, 0, 2, -3])).toBe(0);
32 | });
33 |
34 | it("returns 1 if product is +ve", () => {
35 | expect(arraySign([-1, -2, -3, -4, 3, 2, 1])).toBe(1);
36 | });
37 |
38 | it("returns -1 if product is -ve", () => {
39 | expect(arraySign([-1, 1, -1, 1, -1])).toBe(-1);
40 | });
41 | });
42 |
43 |
44 | const signedArray = (nums) => {
45 | let sign = 1;
46 |
47 | for (let i = 0; i < nums.length; i++) {
48 | if (nums[i] === 0) {
49 | return 0;
50 | } else if (nums[i] < 0) {
51 | sign = -sign;
52 | }
53 | }
54 |
55 | return sign;
56 | };
57 |
58 |
--------------------------------------------------------------------------------
/leetcode/javascript/easy/removeDupsFromSortedArr.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/remove-duplicates-from-sorted-array/
2 | // Test: npm test ./leetcode/easy/removeDupsFromSortedArr.test.js
3 | // 0(n) - time | 0(1) - space
4 |
5 | describe('remove duplicates from sorted array', () => {
6 | it('removes duplicates from sorted array in place', () => {
7 | expect(removeDuplicates([1, 1, 2])).toBe(2)
8 | expect(removeDuplicates([1, 1, 2, 3])).toBe(3)
9 | })
10 | })
11 |
12 | const removeDuplicates = nums => {
13 | let left = 1
14 | let right = 1
15 |
16 | while (right < nums.length) {
17 | if (nums[right] !== nums[right - 1]) {
18 | nums[left] = nums[right]
19 | left++
20 | }
21 | right++
22 | }
23 | return left
24 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/removeElement.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/remove-element/
2 | // Test: npm test ./leetcode/easy/removeElement.test.js
3 | // 0(n) - time | 0(1) - space
4 |
5 | describe('remove element', () => {
6 | it('removes the val element occurence in the array', () => {
7 | expect(removeElement([0, 1, 2, 2, 3, 0, 4, 2], 2).nums).toStrictEqual([0, 1, 3, 0, 4, 0, 4, 2])
8 | expect(removeElement([0, 1, 2, 2, 3, 0, 4, 2], 2).left).toBe(5)
9 | expect(removeElement([], 2)).toBe(0)
10 | })
11 | })
12 |
13 | const removeElement = (nums, val) => {
14 | if (nums.length < 1) return 0
15 |
16 | let left = 0
17 |
18 | for (let right = 0; right < nums.length; right++) {
19 | if (nums[right] !== val) {
20 | nums[left] = nums[right]
21 | left++
22 | }
23 | }
24 | return { nums, left }
25 | };
--------------------------------------------------------------------------------
/leetcode/javascript/easy/reverseLinkedList.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | Test: Run test: npm test ./leetcode/linked-list/reverseLinkedList.test.js
3 |
4 | Source: https://leetcode.com/problems/reverse-linked-list/
5 |
6 | complexity analysis: 0(n) - time | 0(1) - space
7 | */
8 |
9 | describe('reverse linked list', () => {
10 | it('reverses a linked list iteratively', () => {
11 | let list = new SinglyLinkedList()
12 | list.insert(10)
13 | list.insert(20)
14 | list.insert(30)
15 | const reverse = list.reverse()
16 | expect(reverse.data).toBe(30)
17 | expect(reverse.next.next.data).toBe(10)
18 | })
19 | })
20 |
21 | class Node {
22 | constructor(data) {
23 | this.data = data
24 | this.next = null
25 | }
26 | }
27 |
28 | class SinglyLinkedList {
29 | insert(data) {
30 | let newNode = new Node(data)
31 | if (!this.head) {
32 | this.head = newNode
33 | return this.head
34 | }
35 |
36 | let current = this.head
37 | while (current.next) {
38 | current = current.next
39 | }
40 | current.next = newNode
41 | return current
42 | }
43 |
44 | reverse() {
45 | let prev = null
46 | let curr = this.head
47 |
48 | while (curr) {
49 | let nxt = curr.next
50 | curr.next = prev
51 | prev = curr
52 | curr = nxt
53 | }
54 | return prev
55 | }
56 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/romanToInt.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/roman-to-integer/submissions/
2 | // Test: npm test ./leetcode/easy/romanToInt.test.js
3 | //0(n) - time | 0(n) -space
4 |
5 | describe('roman to integer', () => {
6 | it('converts roman to integer', () => {
7 | expect(romanToInt('viii')).toBe(8)
8 | expect(romanToInt('mmi')).toBe(2001)
9 | })
10 | })
11 |
12 | const romanToInt = (s) => {
13 | s = s.toUpperCase()
14 | const hash = {
15 | I: 1,
16 | V: 5,
17 | X: 10,
18 | L: 50,
19 | C: 100,
20 | D: 500,
21 | M: 1000,
22 | }
23 |
24 | let sum = 0
25 | for (let i = 0; i < s.length; i++) {
26 | let curr = hash[s[i]]
27 | let nxt = hash[s[i + 1]]
28 | if (curr < nxt) {
29 | sum -= curr
30 | } else {
31 | sum += curr
32 | }
33 | }
34 | return sum
35 | };
36 |
--------------------------------------------------------------------------------
/leetcode/javascript/easy/sameTree.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/same-tree/
2 | // TEST: npm test ./leetcode/easy/sameTree.test.js
3 |
4 | const BST = require("./BST-testcase.test");
5 |
6 | describe('#Same Tree', () => {
7 | let p, q;
8 |
9 | beforeEach(() => {
10 | p = new BST()
11 | q = new BST()
12 | })
13 |
14 | it('returns true if trees have the same node and value', () => {
15 | p.insert(p.root, 3); p.insert(p.root, 4); p.insert(p.root, 2)
16 | q.insert(q.root, 3); q.insert(q.root, 4); q.insert(q.root, 2)
17 | expect(sameTree(p.root, q.root)).toBe(true)
18 | })
19 |
20 | it('returns false if trees do not have the same node and value', () => {
21 | p.insert(p.root, 3); p.insert(p.root, 4); p.insert(p.root, 2)
22 | q.insert(q.root, 3);
23 | expect(sameTree(p.root, q.root)).toBe(false)
24 | })
25 |
26 | it('returns true if trees are null', () => {
27 | expect(sameTree(p.root, q.root)).toBe(true)
28 | })
29 |
30 | })
31 |
32 | const sameTree = (p, q) => {
33 | if(!p && !q) return true
34 | if(!p || !q || p.data !== q.data) return false
35 | return sameTree(p.left, q.left) && sameTree(p.right, q.right)
36 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/sortArrayByParity.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/sort-array-by-parity/
2 | // Test: npm test ./leetcode/easy/sortArrayByParity.test.js
3 | // 0(n) - time | 0(1) -space
4 |
5 | describe('sort array by parity', () => {
6 | it('odds number comes after even numbers', () => {
7 | expect(sortArrayByParity([1, 0, 3])).toStrictEqual([0, 1, 3])
8 | expect(sortArrayByParity([0, 1, 2])).toStrictEqual([0, 2, 1])
9 | expect(sortArrayByParity([1, 3, 2, 4])).toStrictEqual([4, 2, 3, 1])
10 | })
11 | })
12 |
13 | // l = left pointer, r = right poiter
14 | const sortArrayByParity = function (nums) {
15 | let l = 0
16 | let r = nums.length - 1
17 |
18 |
19 | while (l < r) {
20 | if (isEven(nums[l]) && isEven(nums[r])) {
21 | l++
22 | }
23 |
24 | else if (!isEven(nums[l]) && !isEven(nums[r])) {
25 | r--
26 | }
27 |
28 | else if (!isEven(nums[l]) && isEven(nums[r])) {
29 | swap(nums, l, r)
30 | l++
31 | r--
32 | }
33 |
34 | else {
35 | l++
36 | r--
37 | }
38 |
39 | }
40 |
41 | return nums
42 | };
43 |
44 | const isEven = num => {
45 | return num % 2 === 0
46 | }
47 |
48 | var swap = (arr, s1, s2) => {
49 | [arr[s1], arr[s2]] = [arr[s2], arr[s1]];
50 | }
51 |
--------------------------------------------------------------------------------
/leetcode/javascript/easy/string-swap.test.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | /*
4 | https://leetcode.com/problems/check-if-one-string-swap-can-make-strings-equal/
5 |
6 | complexity analysis
7 | 0(1) - space
8 | 0(n) - time
9 | */
10 |
11 | describe('Check if One String Swap Can Make Strings Equal', () => {
12 | it('returns true if it satisfies the condition', () => {
13 | expect(areAlmostEqual('bank', 'kanb')).toBe(true)
14 | expect(areAlmostEqual('attack', 'defend')).toBe(false)
15 | expect(areAlmostEqual('kelb', 'kelb')).toBe(true)
16 | expect(areAlmostEqual('kelb', 'belk')).toBe(true)
17 | expect(areAlmostEqual('aa', 'ac')).toBe(false)
18 | expect(areAlmostEqual('aaz', 'caa')).toBe(false)
19 | })
20 | })
21 |
22 |
23 | const areAlmostEqual = (s1, s2) => {
24 | if (s1.length !== s2.length) return false
25 |
26 | let count = 0
27 | let index = []
28 |
29 | for (let i = 0; i < s1.length; i++) {
30 | if (s1[i] !== s2[i]) {
31 | count++
32 | index.push(i)
33 | }
34 | }
35 |
36 | let idxOne = index[0]
37 | let idxTwo = index[1]
38 |
39 | if (count > 2 || (s1[idxOne] !== s2[idxTwo] || s1[idxTwo] !== s2[idxOne])) {
40 | return false
41 | }
42 |
43 | return true
44 | }
--------------------------------------------------------------------------------
/leetcode/javascript/easy/twoSum.test.js:
--------------------------------------------------------------------------------
1 | describe('two sum', () => {
2 | it('return the indices', () => {
3 | expect(twoSum([2, 7, 11, 15], 9)).toEqual([0, 1])
4 | expect(twoSum([3, 2, 4], 6)).toEqual([1, 2])
5 | expect(twoSum([3, 3], 6)).toEqual([0, 1])
6 | })
7 | })
8 |
9 | /*
10 | https://leetcode.com/problems/two-sum/
11 |
12 | complexity analysis
13 | 0(n) - time
14 | 0(n) - space
15 | */
16 |
17 | const twoSum = function (nums, target) {
18 | let diff, idx = 0
19 | let map = new Map()
20 |
21 | while (idx < nums.length) {
22 | diff = target - nums[idx]
23 |
24 | if (map.has(diff)) {
25 | return [map.get(diff), idx]
26 | }
27 | map.set(nums[idx], idx)
28 | idx++
29 | }
30 |
31 | return []
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/leetcode/javascript/hard/medianOfSortedArr.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/median-of-two-sorted-arrays/
2 | // Test: npm test ./leetcode/hard/medianOfSortedArr.test.js
3 | // 0(m+n)
4 |
5 | describe('median of sorted arrays', () => {
6 | it('returns the media of sorted arrays', () => {
7 | expect(findMedianSortedArrays([1, 2], [3, 4])).toStrictEqual(2.5)
8 | expect(findMedianSortedArrays([], [1])).toStrictEqual(1)
9 | })
10 | })
11 |
12 | const findMedianSortedArrays = function (num1, num2) {
13 | let num = num1
14 |
15 | for (let i = 0; i < num2.length; i++) {
16 | num.push(num2[i])
17 | }
18 |
19 | num = num.sort((a, b) => a - b)
20 | if (num.length === 1) return num[0]
21 |
22 | let mid = Math.floor(num.length / 2)
23 |
24 | if (num.length % 2 === 0) return (num[mid] + num[mid - 1]) / 2
25 | else return num[mid]
26 | };
--------------------------------------------------------------------------------
/leetcode/javascript/medium/3Sum.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/3sum/
2 | // Test: npm test ./leetcode/medium/3Sum.test.js
3 | // 0(n^2) - time | 0(1) - space
4 |
5 | describe('3 sum', () => {
6 | it('returns possible sum of 3 numbers that sum up to 0', () => {
7 | expect(threeSum([0, 0, 0])).toStrictEqual([[0, 0, 0]])
8 | expect(threeSum([-2, 2, -2, 0, 0])).toStrictEqual([[-2, 0,2]])
9 | expect(threeSum([])).toStrictEqual([])
10 | expect(threeSum([1])).toStrictEqual([])
11 | expect(threeSum([1, 2, 3])).toStrictEqual([])
12 | })
13 | })
14 |
15 | const threeSum = (nums) => {
16 | if (nums.length < 3) return []
17 |
18 | nums = nums.sort((a, b) => a - b)
19 | let validSum = []
20 |
21 | for (let i = 0; i < nums.length; i++) {
22 | if (nums[i] > 0) break
23 | if (i > 0 && nums[i] === nums[i - 1])
24 | continue
25 |
26 |
27 | let left = i + 1
28 | let right = nums.length - 1
29 |
30 | while (left < right) {
31 | const sum = nums[i] + nums[left] + nums[right]
32 |
33 | if (sum === 0) {
34 | validSum.push([nums[i], nums[left], nums[right]])
35 | left++
36 | right--
37 | while (left < right && nums[left] === nums[left - 1]) {
38 | left++
39 | }
40 | } else if (sum < 0) {
41 | left++
42 | } else {
43 | right--
44 | }
45 | }
46 | }
47 | return validSum
48 | };
49 |
50 |
--------------------------------------------------------------------------------
/leetcode/javascript/medium/contains-dupsIII.test.js:
--------------------------------------------------------------------------------
1 |
2 | describe('#contains duplicates III', () => {
3 | it('returns true if array contains duplicates, diff of duplicates(index) <= k && diff of nums <= t', () => {
4 | expect(containsNearbyAlmostDuplicate([3], 3, 0)).toBe(false)
5 | expect(containsNearbyAlmostDuplicate([], 1, 3)).toBe(false)
6 | expect(containsNearbyAlmostDuplicate([1, 2, 3, 1], 3, 0)).toBe(true)
7 | expect(containsNearbyAlmostDuplicate([1,0,1,1,1], 1, 2)).toBe(true)
8 | expect(containsNearbyAlmostDuplicate([1,5,9,1,5,9], 2, 3)).toBe(false)
9 | expect(containsNearbyAlmostDuplicate([-1, -2, 0, 5,-2], 3, 4)).toBe(true)
10 | })
11 | })
12 |
13 | var containsNearbyAlmostDuplicate = function(nums, k, t) {
14 | const buckets = new Map();
15 | const w = t + 1;
16 |
17 | for(let i = 0; i < nums.length; i++){
18 | const idx = Math.floor(nums[i] / w)
19 |
20 | if(buckets.has(idx)){
21 | return true
22 | }
23 |
24 | if(buckets.has(idx - 1) && Math.abs(nums[i] - buckets.get(idx - 1)) < w){
25 | return true
26 | }
27 |
28 | if(buckets.has(idx + 1) && Math.abs(nums[i] - buckets.get(idx + 1)) < w){
29 | return true
30 | }
31 |
32 | buckets.set(idx, nums[i])
33 |
34 | if(i >= k){
35 | const idxOfBucket2Remove = Math.floor(nums[i-k] / w)
36 |
37 | buckets.delete(idxOfBucket2Remove)
38 | }
39 | }
40 |
41 | return false;
42 | };
43 |
44 | const containsNearbyAlmostDuplicate = (nums, k, t) => {
45 | let map = new Map()
46 |
47 | for(let i=0; i {
10 | let obj
11 |
12 | beforeEach(() => {
13 | obj = new WordDictionary()
14 | obj.addWord('bad'); obj.addWord('mad');
15 | obj.addWord('dad');
16 | })
17 |
18 | it('returns true if word is found in the dictionary', () => {
19 | expect(obj.search('pad')).toBe(false)
20 | expect(obj.search('bad')).toBe(true)
21 | expect(obj.search('.ad')).toBe(true)
22 | expect(obj.search('b..')).toBe(true)
23 | })
24 | })
25 |
26 | class WordDictionary {
27 | constructor() {
28 | this.root = {}
29 | }
30 |
31 | addWord(word) {
32 | let node = this.root
33 |
34 | for (const char of word) {
35 | if (!node[char]) node[char] = {}
36 |
37 | node = node[char]
38 | }
39 | node.isEnd = true
40 | }
41 |
42 |
43 | search(word) {
44 |
45 | const dfs = (i, node) => {
46 |
47 | if (i === word.length) {
48 | return node.isEnd || false
49 | }
50 |
51 | const char = word[i]
52 |
53 | if (char === ".") {
54 |
55 | for (const c of Object.keys(node)) {
56 | return (dfs(i + 1, node[c])) || false
57 | }
58 |
59 | } else {
60 | if (!node[char]) return false
61 | return dfs(i + 1, node[char])
62 | }
63 |
64 |
65 | }
66 | return dfs(0, this.root)
67 | }
68 |
69 | }
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/leetcode/javascript/medium/getTargetCopy.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/find-a-corresponding-node-of-a-binary-tree-in-a-clone-of-that-tree/
2 | // TEST: npm test ./leetcode/medium/getTargetCopy.test.js
3 | // 0(n) - time | 0(1) - space
4 |
5 | const BST = require("../easy/BST-testcase.test");
6 |
7 | describe('#Get target copy from a cloned BT', () => {
8 | let p, q;
9 |
10 | beforeEach(() => {
11 | p = new BST()
12 | p.insert(p.root, 60); p.insert(p.root, 10)
13 | p.insert(p.root, 40); p.insert(p.root, 70)
14 | p.insert(p.root, 20); p.insert(p.root, 5)
15 | q = p.copy()
16 | })
17 |
18 | it('returns the target in the cloned tree', () => {
19 | expect(getTargetCopy(p.root, q, 20).data).toBe(20)
20 | expect(getTargetCopy(p.root, q, 60).data).toBe(60)
21 | })
22 | })
23 |
24 |
25 |
26 | const getTargetCopy = (original, cloned, target) => {
27 | if (!original || !cloned) return
28 | const dfs = (original, copy) => {
29 | if (!original) return
30 |
31 | if (original.data === target) return copy // in leetcode playground, compare the original node, not just the target. This will cover the edge case of duplicate values
32 |
33 | let left = dfs(original.left, copy.left)
34 | let right = dfs(original.right, copy.right)
35 |
36 | return left || right
37 | }
38 |
39 | return dfs(original, cloned)
40 | }
--------------------------------------------------------------------------------
/leetcode/javascript/medium/implementTrie.test.js:
--------------------------------------------------------------------------------
1 | //TEST: npm test ./leetcode/medium/implementTrie.test.js
2 |
3 | describe('#Implement Trie Data structure', () => {
4 | let myTrie;
5 |
6 | beforeEach(() => {
7 | myTrie = new Trie()
8 | myTrie.insert('gorilla'); myTrie.insert('gotham'); myTrie.insert('boo');
9 | })
10 |
11 | it('inserts string into trie', () => {
12 | expect(myTrie.root.g).toBeDefined()
13 | expect(myTrie.root.n).toBeUndefined()
14 | })
15 |
16 | it('searches for string in trie', () => {
17 | expect(myTrie.search('golang')).toEqual(false)
18 | expect(myTrie.search('boo')).toEqual(true)
19 | })
20 |
21 | it('finds prefix of string in trie', () => {
22 | expect(myTrie.startsWith('go')).toEqual(true)
23 | expect(myTrie.startsWith('boom')).toEqual(false)
24 | })
25 | })
26 |
27 | class Trie {
28 | constructor() {
29 | this.root = {}
30 | }
31 |
32 | insert(word) {
33 | let node = this.root
34 |
35 | for (const char of word) {
36 | if (!node[char]) {
37 | node[char] = {}
38 | }
39 | node = node[char]
40 | }
41 | node.isEnd = true
42 | }
43 |
44 | search(word) {
45 | let node = this.root
46 |
47 | for (const char of word) {
48 | if (!node[char]) return false
49 | node = node[char]
50 | }
51 |
52 | return node.isEnd || false
53 | }
54 |
55 | startsWith(prefix) {
56 | let node = this.root
57 |
58 | for (const char of prefix) {
59 | if (!node[char]) return false
60 | node = node[char]
61 | }
62 |
63 | return true
64 | }
65 | }
--------------------------------------------------------------------------------
/leetcode/javascript/medium/longestSubstring.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/longest-substring-without-repeating-characters/
2 | // Test: npm test ./leetcode/medium/longestSubstring.test.js
3 | // 0(n) - time | 0(1) - space
4 |
5 | describe('longest substring without returning characters', () => {
6 | it('returns the count of the longest substring', () => {
7 | expect(lengthOfLongestSubstring('abcd08=ab')).toBe(7)
8 | expect(lengthOfLongestSubstring('wikew')).toBe(4)
9 | })
10 | })
11 |
12 | const lengthOfLongestSubstring = str => {
13 | let max = 0
14 | let left = 0
15 | let set = new Set()
16 |
17 | for (let right = 0; right < str.length; right++) {
18 | while (set.has(str[right])) {
19 | set.delete(str[left])
20 | left++
21 | }
22 |
23 | set.add(str[right])
24 | max = Math.max(max, right - left + 1)
25 | }
26 | return max
27 | };
--------------------------------------------------------------------------------
/leetcode/javascript/medium/maxOperations.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/max-number-of-k-sum-pairs
2 | // Test: npm test ./leetcode/medium/maxOperations.test.js
3 |
4 | describe('max operation', () => {
5 | it('returns the number of possible sums for k', () =>{
6 | expect(maxOperationsTwo([2,5,4,4,1,3,4,4,1,4,4,1,2,1,2,2,3,2,4,2], 3)).toBe(4)
7 | expect(maxOperations([3,1,3,4,3], 6)).toBe(1)
8 | expect(maxOperations([], 2)).toBe(0)
9 | })
10 | })
11 |
12 | // 0(n) - time | 0(n) - space
13 | const maxOperations = (nums, k) => {
14 | let map = new Map()
15 | let count = 0
16 |
17 | for (let n of nums){
18 | let diff = k - n
19 |
20 | if(diff > 0 && map.get(diff) > 0){
21 | count++
22 | map.set(diff, map.get(diff) - 1)
23 | } else{
24 | map.set(n, (map.get(n) || 0) + 1)
25 | }
26 | }
27 |
28 | return count
29 | }
30 |
31 | // 0(nlogn) - time | 0(1) - space
32 | const maxOperationsTwo = (nums, k) => {
33 | nums = nums.sort((a,b) => a - b)
34 |
35 | let left = 0
36 | let right = nums.length - 1
37 | let count = 0
38 |
39 | while(left < right){
40 | if (nums[left] + nums[right] < k) left++
41 | else if (nums[left] + nums[right] > k) right--
42 | else{
43 | left++
44 | right--
45 | count++
46 | }
47 | }
48 |
49 | return count
50 | };
--------------------------------------------------------------------------------
/leetcode/javascript/medium/maxProfitII.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/
2 | // Test: npm test ./leetcode/medium/maxProfitII.test.js
3 | //0(n) - time | 0(1) - space
4 |
5 | describe('#max profit', () => {
6 | it('returns the max profit from buying and selling stocks', () => {
7 | expect(maxProfit([7,1,5,3,6,4])).toBe(7)
8 | expect(maxProfit([1,2,3,4,5])).toBe(4)
9 | expect(maxProfit([7,6,4,3,1])).toBe(0)
10 | expect(maxProfit([])).toBe(0)
11 | expect(maxProfit([0, -1, 4, 5])).toBe(6)
12 | })
13 | })
14 |
15 | const maxProfit = nums => {
16 | let profit = 0
17 |
18 | for(let i = 0; i < nums.length; i++){
19 | if(nums[i + 1] > nums[i]){
20 | profit += (nums[i + 1] - nums[i])
21 | }
22 | }
23 |
24 | return profit
25 | }
--------------------------------------------------------------------------------
/leetcode/javascript/medium/reverseInteger.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/reverse-integer/
2 | // test: npm test ./leetcode/medium/reverseInteger.test.js
3 | // 0(n) - time | 0(1) - space
4 |
5 | describe('reverse 2 bit integer', () => {
6 | it('expects to reverse 32 bit integer', () => {
7 | expect(reverse(120)).toBe(21)
8 | expect(reverse(-123)).toBe(-321)
9 | })
10 | it('expects to return 0 for integers larger or less than 32 bit', () => {
11 | expect(reverse(1534236469)).toBe(0)
12 | expect(reverse(-(2**31))).toBe(0)
13 | })
14 | })
15 |
16 | const reverse = x => {
17 | let res = 0
18 | let sign = Math.sign(x)
19 | let min = -(2**31)
20 | let max = (2**31) - 1
21 |
22 | console.log({min, max})
23 | console.log(Math.floor(max / 10))
24 |
25 | if(sign === -1){
26 | x = x * sign
27 | }
28 |
29 |
30 | while(x){
31 | let digit = x % 10
32 | x = Math.floor(x/10)
33 |
34 | if (res > Math.floor(max/10) || res === Math.floor(max/10) && digit >= max % 10){ return 0}
35 | if (res < Math.floor(min/10) || res === Math.floor(min/10) && digit <= min % 10) { return 0 }
36 |
37 | res = (res * 10) + digit
38 | }
39 |
40 | return res*sign
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/leetcode/javascript/medium/subsets.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/subsets/
2 | //Test: npm test ./leetcode/medium/subsets.test.js
3 | //0(n * 2^n) - time | 0(n) - space
4 |
5 | describe('#subsets', () => {
6 | it('returns the subsets of a given array', () => {
7 | expect(subsets([1, 2, 3])).toStrictEqual([[1, 2, 3], [1, 2], [1, 3], [1], [2, 3], [2], [3], []])
8 | expect(subsets([0])).toStrictEqual([[0], []])
9 | })
10 | })
11 |
12 | const subsets = nums => {
13 | let res = []
14 | let subsets = []
15 |
16 | const dfs = i => {
17 | if (i >= nums.length) {
18 | res.push([...subsets])
19 | return
20 | }
21 |
22 | subsets.push(nums[i])
23 | dfs(i + 1)
24 |
25 | subsets.pop()
26 | dfs(i + 1)
27 | }
28 | dfs(0)
29 | return res
30 | }
--------------------------------------------------------------------------------
/leetcode/javascript/medium/twoSum-ii.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/
2 | // npm test ./leetcode/medium/twoSum-ii.test.js
3 | // 0(n) - time | 0(1) - space
4 |
5 | describe('Two sum II: 1-indexed array', () => {
6 | it('returns the indices of numbers that sum up to target', () =>{
7 | expect(twoSum([2, 7, 11, 15], 9)).toStrictEqual([1, 2])
8 | expect(twoSum([2, 3, 4], 6)).toStrictEqual([1, 3])
9 | expect(twoSum([3, 3, 4, 9, 8], 12)).toStrictEqual([3, 5])
10 | })
11 | })
12 |
13 | /*
14 | complexity analysis
15 | */
16 |
17 | const twoSum = (numbers, target) => {
18 | let left = 0
19 | let right = numbers.length - 1
20 |
21 | while (left < right){
22 | let sum = numbers[left] + numbers[right]
23 |
24 | if(sum > target) right--
25 | else if (sum < target) left++
26 | else return [left+1, right+1]
27 | }
28 | }
--------------------------------------------------------------------------------
/leetcode/javascript/medium/unsortedSubArray.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/shortest-unsorted-continuous-subarray/
2 | // Test: npm test ./leetcode/medium/unsortedSubArray.test.js
3 | // 0(n) - time | 0(1) - space
4 |
5 | describe('unsorted sub array', () => {
6 | it('returns the length of unsorted subarray', () => {
7 | expect(findUnsortedSubarray([4, 6, 3, 2, 7, 5, 8])).toBe(6)
8 | expect(findUnsortedSubarray([1, 3, 2, 4, 5])).toBe(2)
9 | expect(findUnsortedSubarray([])).toBe(0)
10 | })
11 | })
12 |
13 |
14 | const findUnsortedSubarray = function (nums) {
15 | let start = 0
16 | let end = nums.length - 1
17 |
18 | while (start + 1 < nums.length && nums[start] <= nums[start + 1]) start++
19 |
20 | while (end - 1 >= 0 && nums[end] >= nums[end - 1]) end--
21 |
22 | if (start === nums.length - 1) return 0
23 |
24 | let min = +Infinity
25 | let max = -Infinity
26 |
27 | for (let i = start; i <= end; i++) {
28 | min = Math.min(min, nums[i])
29 | max = Math.max(max, nums[i])
30 | }
31 | while (start - 1 >= 0 && nums[start - 1] > min) start--
32 |
33 | while (end + 1 <= nums.length && nums[end + 1] < max) end++
34 |
35 | return end - start + 1
36 | }
37 |
--------------------------------------------------------------------------------
/leetcode/python/BFS/jumpGameIII.py:
--------------------------------------------------------------------------------
1 | from typing import Deque, List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/jump-game-iii/
6 | 0(n) - tc | 0(n) - sc
7 | '''
8 |
9 |
10 | class Solution:
11 | def canReach(self, arr: List[int], start: int) -> bool:
12 | queue = Deque([start])
13 | visited = set()
14 |
15 | while queue:
16 | idx = queue.popleft()
17 |
18 | if idx in visited:
19 | continue
20 | visited.add(idx)
21 |
22 | if arr[idx] == 0:
23 | return True
24 | else:
25 | if idx - arr[idx] >= 0:
26 | queue.append(idx - arr[idx])
27 | if idx + arr[idx] < len(arr):
28 | queue.append(idx + arr[idx])
29 | return False
30 |
31 | class Test(unittest.TestCase):
32 | def test_canReach(self):
33 | self.assertEqual(Solution.canReach(self, [3,0,2,1,2], 2), False)
34 | self.assertEqual(Solution.canReach(self, [4,2,3,0,3,1,2], 5), True)
35 |
36 | if __name__ == "__main__":
37 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/bit-manipulation/countingBits.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/counting-bits/
6 | 0(n log n) - tc | 0(n) - sc
7 | '''
8 |
9 | class Solution:
10 | def countBitsDp(self, n:int) -> List[int]:
11 | dp = [0] * (n + 1)
12 | offset = 1
13 |
14 | for i in range(1, n + 1):
15 | if offset * 2 == i:
16 | offset = i
17 | dp[i] = 1 + dp[i - offset]
18 | return dp
19 |
20 | def countBits(self, n: int) -> List[int]:
21 | ans = []
22 |
23 | for i in range(n + 1):
24 | convertToBin = bin(i)
25 | ans.append(convertToBin.count('1'))
26 | return ans
27 |
28 | class Test(unittest.TestCase):
29 | def test_countBits(self):
30 | self.assertEqual(Solution.countBits(self, 2), [0,1,1])
31 | self.assertEqual(Solution.countBits(self, 5), [0,1,1,2,1,2])
32 |
33 | def test_countBitsDP(self):
34 | self.assertEqual(Solution.countBits(self, 1), [0,1])
35 | self.assertEqual(Solution.countBits(self, 0), [0])
36 |
37 |
38 | if __name__ == "__main__":
39 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/bit-manipulation/hammingWeight.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/number-of-1-bits/
5 | 0(1) - tc | 0(1) - sc
6 | '''
7 |
8 | class Solution:
9 | def hammingWeight(self, n) -> int:
10 | n = int(n)
11 | count = 0
12 | while n:
13 | count += n % 2
14 | n = n // 2
15 | return count
16 |
17 | def hammingWeightTwo(self, n) -> int:
18 | n = int(n)
19 | print(n)
20 | count = 0
21 | while n:
22 | if n & 1:
23 | count += 1
24 | n = n >> 1
25 | return count
26 |
27 |
28 |
--------------------------------------------------------------------------------
/leetcode/python/bit-manipulation/reverseBits.py:
--------------------------------------------------------------------------------
1 | '''
2 | https://leetcode.com/problems/reverse-bits/
3 | 0(1) - tc & sc
4 | '''
5 |
6 | class Solution:
7 | def reverseBits(self, n: int) -> int:
8 | pos = 31
9 | rvd = 0
10 |
11 | while pos >= 0 and n:
12 | if n & 1:
13 | rvd = rvd | (1 << pos)
14 | n >>= 1
15 | pos -= 1
16 | return rvd
17 |
18 |
--------------------------------------------------------------------------------
/leetcode/python/bit-manipulation/reverseInt.py:
--------------------------------------------------------------------------------
1 | import math, unittest
2 |
3 | class Solution:
4 | def reverse(self, x: int) -> int:
5 | MIN = -2147483648
6 | MAX = 2147483647
7 | res = 0
8 |
9 | while x:
10 | digit = int(math.fmod(x, 10))
11 | x = int(x / 10)
12 |
13 | if (res > MAX // 10 or (res == MAX // 10 and digit >= MAX % 10)):
14 | return 0
15 |
16 | if (res < MIN // 10 or (res == MIN // 10 and digit <= MIN % 10)):
17 | return 0
18 |
19 | res = (res * 10) + digit
20 |
21 | return res
22 |
23 | class Test(unittest.TestCase):
24 | def test_reverse(self):
25 | self.assertEqual(Solution.reverse(self, -123), -321)
26 | self.assertEqual(Solution.reverse(self, 1534236469), 0)
27 |
28 | if __name__ == "__main__":
29 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/bit-manipulation/sumTwoInt.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/sum-of-two-integers/
5 | 0(1) - tc & sc
6 | '''
7 |
8 | class Solution:
9 | def getSum(self, a: int, b: int) -> int:
10 | def add(a, b):
11 | if not a or not b:
12 | return a or b
13 | return add(a^b, (a & b) << 1)
14 | if a * b < 0:
15 | if a > 0:
16 | return self.getSum(b, a)
17 | if add(~a, 1) == b:
18 | return 0
19 | if add(~a, 1) < b:
20 | return add(~add(add(~a, 1), add(~b, 1)), 1)
21 | return add(a, b)
22 |
23 | class Test(unittest.TestCase):
24 | def test_getSum(self):
25 | self.assertEqual(Solution.getSum(self, 2, 3), 5)
26 | self.assertEqual(Solution.getSum(self, 1, 2), 3)
27 |
28 | if __name__ == "__main__":
29 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/easy/climbStairs.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/climbing-stairs/
5 | 0(n) - TC | 0(n) - SC
6 | '''
7 |
8 | def climbStairs(n) -> int:
9 | one, two = 1, 1
10 |
11 | for i in range (n - 1):
12 | temp = one
13 | one = one + two
14 | two = temp
15 |
16 | return one
17 |
18 | def climbStairsRecursive(n) -> int:
19 | memo = {}
20 |
21 | def recurse(n):
22 | if n in memo:
23 | return memo[n]
24 | if n == 1:
25 | return 1
26 | if n == 2:
27 | return 2
28 | memo[n] = recurse(n - 1) + recurse(n - 2)
29 | return memo[n]
30 |
31 | return recurse(n)
32 |
33 | print(climbStairsRecursive(38))
34 | class Test(unittest.TestCase):
35 | def test_climbStairs(self):
36 | self.assertEqual(climbStairsRecursive(2), 2)
37 | self.assertEqual(climbStairsRecursive(3), 3)
38 | self.assertEqual(climbStairsRecursive(5), 8)
39 | self.assertEqual(climbStairsRecursive(38), 63245986)
40 |
41 |
42 | if __name__ == "__main__":
43 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/easy/findJudge.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 |
3 | '''
4 | https://leetcode.com/problems/find-the-town-judge/
5 | 0(n) - sc | 0(n) -tc
6 | '''
7 |
8 | def trustJudge(n, trust:List[List[int]]) -> int:
9 | trust_board = [0] * (n + 1)
10 |
11 | for person1, person2 in trust:
12 | trust_board[person2] += 1
13 | trust_board[person1] -= 1
14 |
15 | for i in range(1, n + 1):
16 | if trust_board[i] == n - 1:
17 | return i
18 | return -1
19 |
20 |
21 | print(trustJudge(3, [[1,2], [2,3]]))
--------------------------------------------------------------------------------
/leetcode/python/easy/isAnagram.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/valid-anagram/
5 | '''
6 |
7 | #0(n log n) - tc & sc
8 | class Solution:
9 | def isAnagram(self, s: str, t: str) -> bool:
10 | def sortStr(letter):
11 | letter = sorted(letter)
12 | newLetter = ''.join(letter)
13 | return newLetter
14 |
15 | return sortStr(s) == sortStr(t)
16 |
17 | #0(s + t) - tc & sc
18 | class SolutionTwo:
19 | def isAnagram(self, s: str, t: str) -> bool:
20 | if len(s) != len(t):
21 | return False
22 | countS, countT = {}, {}
23 |
24 | for i in range(len(s)):
25 | countS[s[i]] = 1 + countS.get(s[i], 0)
26 | countT[t[i]] = 1 + countT.get(t[i], 0)
27 |
28 | for c in countS:
29 | if countS[c] != countT.get(c, 0):
30 | return False
31 | return True
32 |
33 | class Test(unittest.TestCase):
34 | def test_solutionOne(self):
35 | self.assertEqual(Solution.isAnagram(self, 'anagram', 'nagaram'), True)
36 | self.assertEqual(Solution.isAnagram(self, 'rat', 'car'), False)
37 | self.assertEqual(Solution.isAnagram(self, 'rat', 'ca'), False)
38 | self.assertEqual(Solution.isAnagram(self, '', ''), True)
39 | self.assertEqual(Solution.isAnagram(self, '', 'b'), False)
40 | self.assertEqual(Solution.isAnagram(self, ' ', ' '), True)
41 |
42 | def test_solutionTwo(self):
43 | self.assertEqual(SolutionTwo.isAnagram(self, 'anagram', 'nagaram'), True)
44 | self.assertEqual(SolutionTwo.isAnagram(self, 'rat', 'car'), False)
45 | self.assertEqual(SolutionTwo.isAnagram(self, 'rat', 'ca'), False)
46 | self.assertEqual(SolutionTwo.isAnagram(self, '', ''), True)
47 | self.assertEqual(SolutionTwo.isAnagram(self, '', 'b'), False)
48 | self.assertEqual(SolutionTwo.isAnagram(self, ' ', ' '), True)
49 |
50 | if __name__ == "__main__":
51 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/easy/maxProfit.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
6 | 0(n) - tc | 0(1) - sc
7 | '''
8 |
9 | class Solution:
10 | def maxProfit(self, nums: List[int]) -> int:
11 | left, right = 0, 1
12 | profit = 0
13 |
14 | while right < len(nums):
15 | if nums[right] < nums[left]:
16 | left += 1
17 | else:
18 | profit = max(profit, nums[right] - nums[left])
19 | right += 1
20 | return profit
21 |
22 | class Test(unittest.TestCase):
23 | def test_maxProfit(self):
24 | self.assertEqual(Solution.maxProfit(self, [7,1,5,3,6,4]), 5)
25 | self.assertEqual(Solution.maxProfit(self, [7,6,4,3,1]), 0)
26 | self.assertEqual(Solution.maxProfit(self, [1]), 0)
27 | self.assertEqual(Solution.maxProfit(self, [1, 1]), 0)
28 | self.assertEqual(Solution.maxProfit(self, [0, 1]), 1)
29 | self.assertEqual(Solution.maxProfit(self, []), 0)
30 |
31 | if __name__ == "__main__":
32 | unittest.main()
33 |
--------------------------------------------------------------------------------
/leetcode/python/easy/mergeSortedArr.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/merge-sorted-array/
6 | 0(n + m) - TC | 0(1) - SC
7 | '''
8 |
9 | def merge(nums1:List[int], nums2:List[int], m:int, n:int) -> None:
10 | last = m + n - 1
11 |
12 | while m > 0 and n > 0:
13 | if nums1[m - 1] > nums2[n - 1]:
14 | nums1[last] = nums1[m - 1]
15 | m -= 1
16 | else:
17 | nums1[last] = nums2[n - 1]
18 | n -= 1
19 | last -= 1
20 |
21 |
22 | while n > 0:
23 | nums1[last] = nums2[n - 1]
24 | n -= 1
25 | last -= 1
26 |
27 | return nums1
28 |
29 |
30 | class Test(unittest.TestCase):
31 | def test_merge(self):
32 | fn = merge([1, 2, 3, 0, 0, 0], [2,5,6], 3, 3)
33 | self.assertEqual(fn, [1, 2,2,3,5,6])
34 |
35 |
36 | if __name__ == '__main__':
37 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/easy/minCostClimbingStairs.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/min-cost-climbing-stairs/
6 | 0(n) - tc | 0(n) - sc
7 | '''
8 |
9 | class Solution:
10 | def minCostClimbingStairs(self, cost: List[int]) -> int:
11 | cost.append(0)
12 |
13 | for i in range(len(cost) - 3, -1, -1):
14 | cost[i] += min(cost[i + 1], cost[i + 2])
15 |
16 | return min(cost[0], cost[1])
17 |
18 | class Test(unittest.TestCase):
19 | def test_minCost(self):
20 | self.assertEqual(Solution.minCostClimbingStairs(self, [10,15,20]), 15)
21 | self.assertEqual(Solution.minCostClimbingStairs(self, [1,100,1,1,1,100,1,1,100,1]), 6)
22 |
23 | if __name__ == "__main__":
24 | unittest.main()
25 |
--------------------------------------------------------------------------------
/leetcode/python/easy/removePalindromeSub.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/remove-palindromic-subsequences/
5 | 0(n) - TC | 0(1) - SC
6 | '''
7 |
8 | def removePalindromeSub(str) -> int:
9 | i, j = 0, len(str) - 1
10 |
11 | while i < j:
12 | if str[i] != str[j]:
13 | return 2
14 | i += 1
15 | j -= 1
16 | return 1
17 |
18 | class Test(unittest.TestCase):
19 | def test_solution(self):
20 | self.assertEqual(removePalindromeSub('baabb'), 2)
21 | self.assertEqual(removePalindromeSub("bbaabaaa"), 2)
22 | self.assertEqual(removePalindromeSub('ababa'), 1)
23 |
24 | if __name__ == "__main__":
25 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/easy/runningSum.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | """
5 | https://leetcode.com/problems/running-sum-of-1d-array/
6 | 0(n) - TC | 0(1) - SC
7 | """
8 |
9 | def runningSum(nums:List[int]) -> List[int]:
10 | for i in range(1, len(nums)):
11 | nums[i] = nums[i] + nums[i - 1]
12 |
13 | return nums
14 |
15 |
16 | class Test(unittest.TestCase):
17 | def test_runningSum(self):
18 | self.assertEqual(runningSum([1,1,1,2,2,3]), [1,2,3,5,7,10])
19 | self.assertEqual(runningSum([]), [])
20 | self.assertEqual(runningSum([1]), [1])
21 | self.assertEqual(runningSum([-1, 1, 2]), [-1, 0, 2])
22 |
23 |
24 | if __name__ == "__main__":
25 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/easy/test_kthLargest.py:
--------------------------------------------------------------------------------
1 | import unittest, heapq
2 | from pip import List
3 |
4 | """
5 | https://leetcode.com/problems/kth-largest-element-in-a-stream/
6 | 0(n log k) - TC | 0(1) - space
7 | """
8 |
9 | class KthLargest:
10 | def __init__(self, k:int, nums: List[int]):
11 | self.minHeap = nums
12 | self.k = k
13 | heapq.heapify(self.minHeap)
14 | while len(self.minHeap) > k:
15 | heapq.heappop(self.minHeap)
16 |
17 | def add(self, val:int) -> int:
18 | heapq.heappush(self.minHeap, val)
19 | if len(self.minHeap) > self.k:
20 | heapq.heappop(self.minHeap)
21 | return self.minHeap[0]
22 |
23 | class TestKthLargest(unittest.TestCase):
24 | def test_kthLargest(self):
25 | heap = KthLargest(3, [4,5,8,2])
26 | result = heap.add(3)
27 | self.assertEqual(result, 4)
28 |
29 | if __name__ == "__main__":
30 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/easy/test_twoSum.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 |
5 | class Solution:
6 | def twoSum(self, nums:List[int], target:int )->int:
7 | hash = {}
8 | i = 0
9 |
10 | while i < len(nums):
11 | diff = target - nums[i]
12 | if diff in hash:
13 | return [hash[diff], i]
14 | hash[nums[i]] = i
15 | i += 1
16 |
17 |
18 | class TestTwoSum(unittest.TestCase):
19 | def test_twoSum(self):
20 | result = Solution.twoSum(self, [2,7,11,15], 9)
21 | result_two = Solution.twoSum(self, [3,2,4], 6)
22 | self.assertEqual(result, [0,1])
23 | self.assertEqual(result_two, [1,2])
24 |
25 | if __name__ == "__main__":
26 | unittest.main()
27 |
28 |
--------------------------------------------------------------------------------
/leetcode/python/easy/transposeMatrix.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | """
5 | https://leetcode.com/problems/transpose-matrix/
6 | 0(R * C) TC | SC - rows * cols of given matrix
7 | """
8 |
9 | class Solution:
10 | def transpose(self, matrix:List[List[int]]) -> List[List[int]]:
11 | rows, cols = len(matrix), len(matrix[0])
12 | transposed = []
13 |
14 | for i in range(rows):
15 | transposed.append([])
16 | for j in range(cols):
17 | transposed[i].append(matrix[j][i])
18 |
19 | return transposed
20 |
21 | class TestTranspose(unittest.TestCase):
22 | def test_transpose(self):
23 | sol = Solution.transpose(self, [[2, 4, -1], [-10, 5, 11], [18, -7, 6]])
24 | self.assertEqual(sol, [[2, -10, 18], [4, 5, -7], [-1, 11, 6]])
25 |
26 | if __name__ == "__main__":
27 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/easy/twoSum.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | Leetcode 1: https://leetcode.com/problems/two-sum/
6 | 0(n) - tc | 0(n) - sc
7 | '''
8 |
9 | class Solution:
10 | def twoSum(self, nums: List[int], target: int) -> List[int]:
11 | store = {}
12 | for i in range(len(nums)):
13 | diff = target - nums[i]
14 | if diff in store:
15 | return [store[diff], i]
16 | store[nums[i]] = i
17 |
18 |
19 | class Test(unittest.TestCase):
20 | def test_twoSum(self):
21 | self.assertEqual(Solution.twoSum(self, [3, 3], 6), [0, 1])
22 | self.assertEqual(Solution.twoSum(self, [2,7,11,15], 9), [0, 1])
23 | self.assertEqual(Solution.twoSum(self, [3,2,4], 6), [1, 2])
24 |
25 |
26 | if __name__ == "__main__":
27 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/easy/validPalindrome.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/valid-palindrome/
5 | 0(n) - tc | 0(1) - sc
6 | '''
7 |
8 | class Solution:
9 | def isPalindrome(self, s: str) -> bool:
10 | s = s.lower().replace(' ', '')
11 | l, r = 0, len(s) - 1
12 |
13 |
14 | while l < r:
15 | if not s[l].isalnum():
16 | l += 1
17 | continue
18 | if not s[r].isalnum():
19 | r -= 1
20 | continue
21 | if s[l] != s[r]:
22 | return False
23 | l += 1
24 | r -= 1
25 | return True
26 |
27 | class Test(unittest.TestCase):
28 | def test_validPalindrom(self):
29 | self.assertEqual(Solution.isPalindrome(self, "A man, a plan, a canal: Panama"), True)
30 | self.assertEqual(Solution.isPalindrome(self, ",."), True)
31 | self.assertEqual(Solution.isPalindrome(self, "race a car"), False)
32 | self.assertEqual(Solution.isPalindrome(self, " "), True)
33 |
34 | if __name__ == "__main__":
35 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/easy/validParentheses.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/valid-parentheses/
5 | 0(n) - tc & 0(n) - sc
6 | '''
7 | class Solution:
8 | def isValid(self, s: str) -> bool:
9 | stack = []
10 |
11 | for item in s:
12 | lastItem = stack and stack[-1]
13 | if lastItem == "(" and item == ")":
14 | stack.pop()
15 | elif lastItem == "[" and item == "]":
16 | stack.pop()
17 | elif lastItem == "{" and item == "}":
18 | stack.pop()
19 | else:
20 | stack.append(item)
21 | return len(stack) == 0
22 |
23 | class Test(unittest.TestCase):
24 | def test_isValid(self):
25 | self.assertEqual(Solution.isValid(self, '([])'), True)
26 | self.assertEqual(Solution.isValid(self, '([)]'), False)
27 | self.assertEqual(Solution.isValid(self, '()[]{}'), True)
28 |
29 | if __name__ == "__main__":
30 | unittest.main()
31 |
32 |
--------------------------------------------------------------------------------
/leetcode/python/easy/validPath.py:
--------------------------------------------------------------------------------
1 |
2 | #Input: n = 6, edges = [[0,1],[0,2],[3,5],[5,4],[4,3]], source = 0,
3 |
4 | def vp(n, edges):
5 | adjacencyList = [[] for _ in range(n)]
6 | for node1, node2 in edges:
7 | adjacencyList[node1].append(node2)
8 | adjacencyList[node2].append(node1)
9 | print(adjacencyList)
10 |
11 | vp(6, [[0,1],[0,2],[3,5],[5,4],[4,3]])
--------------------------------------------------------------------------------
/leetcode/python/greedy/gasStation.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/gas-station/
6 | 0(n) - tc | 0(1) - sc
7 | '''
8 |
9 |
10 | class Solution:
11 | def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
12 | if sum(gas) < sum(cost):
13 | return -1
14 |
15 | total, res = 0, 0
16 |
17 | for i in range(len(gas)):
18 | total += (gas[i] - cost[i])
19 |
20 | if total < 0:
21 | total = 0
22 | res = i + 1
23 | return res
24 |
25 |
26 | class Test(unittest.TestCase):
27 | def test_canCompleteCircuit(self):
28 | self.assertEqual(Solution.canCompleteCircuit(self, [2, 3, 4], [3, 4, 3]), -1)
29 | self.assertEqual(Solution.canCompleteCircuit(self, [1,2,3,4,5], [3,4,5,1,2]), 4)
30 |
31 |
32 | if __name__ == "__main":
33 | unittest.main()
34 |
--------------------------------------------------------------------------------
/leetcode/python/greedy/handsOfStraights.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest, heapq
3 |
4 | '''
5 | https://leetcode.com/problems/hand-of-straights/
6 | 0(n) - tc | 0(n) - sc
7 | '''
8 |
9 | class Solution:
10 | def isNStraightHand(self, hand: List[int], groupSize: int) -> bool:
11 | if len(hand) % groupSize != 0:
12 | return False
13 |
14 | count = {}
15 | for n in hand:
16 | count[n] = 1 + count.get(n, 0)
17 |
18 | minHeap = list(count.keys())
19 | heapq.heapify(minHeap)
20 |
21 | while minHeap:
22 | minVal = minHeap[0]
23 |
24 | for num in range(minVal, minVal + groupSize):
25 | if num not in count:
26 | return False
27 | count[num] -= 1
28 |
29 | if count[num] == 0:
30 | if num != minHeap[0]:
31 | return False
32 | heapq.heappop(minHeap)
33 | return True
34 |
35 | class Test(unittest.TestCase):
36 | def test_isNStraightHand(self):
37 | self.assertEqual(Solution.isNStraightHand(self, [1, 0], 3), False)
38 | self.assertEqual(Solution.isNStraightHand(self, [8, 10, 12], 3), False)
39 | self.assertEqual(Solution.isNStraightHand(self, [1,2,3,6,2,3,4,7,8], 3), True)
40 | self.assertEqual(Solution.isNStraightHand(self, [1,2,3,4,5], 4), False)
41 |
42 | if __name__ == "__main__":
43 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/greedy/jumpGame.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | Medium
6 | https://leetcode.com/problems/jump-game/
7 | 0(n) - tc | 0(1) - sc
8 | '''
9 |
10 | class Solution:
11 | def canJump(self, nums: List[int]) -> bool:
12 | goal = len(nums) - 1
13 |
14 | for i in range(len(nums) -1, -1, -1):
15 | if i + nums[i] >= goal:
16 | goal = i
17 | return True if goal == 0 else False
18 |
19 | class Test(unittest.TestCase):
20 | def test_canJump(self):
21 | self.assertEqual(Solution.canJump(self, [2,3,1,1,4]), True)
22 | self.assertEqual(Solution.canJump(self, [3,2,1,0,4]), False)
23 |
24 | if __name__ == "__main__":
25 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/greedy/jumpGameII.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/jump-game-ii/
6 | 0(n) - tc | 0(1) - sc
7 | '''
8 |
9 | class Solution:
10 | def jump(self, nums: List[int]) -> int:
11 | res = 0
12 | l = r = 0
13 |
14 | while r < len(nums) - 1:
15 | farthest = 0
16 | for i in range(l, r + 1):
17 | farthest = max(farthest, i + nums[i])
18 | l = r + 1
19 | r = farthest
20 | res += 1
21 | return res
22 |
23 | class Test(unittest.TestCase):
24 | def test_jump(self):
25 | self.assertEqual(Solution.jump(self, [2,3,1,1,4]), 2)
26 | self.assertEqual(Solution.jump(self, [2,3,0,1,4]), 2)
27 |
28 | if __name__ == "__main__":
29 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/hard/nQueens.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/n-queens/
6 | 0(2 ^ N) - TC | 0(N ^ 2) - SC
7 | '''
8 |
9 | class Solution:
10 | def solveNQueens(self, n: int) -> List[List[str]]:
11 | col = set()
12 | posDiag = set()
13 | negDiag = set()
14 |
15 | res = []
16 | board = [["."] * n for i in range(n)]
17 |
18 | def backtrack(r):
19 | if r == n:
20 | copy = ["".join(row) for row in board]
21 | res.append(copy)
22 | return
23 |
24 | for c in range(n):
25 | if c in col or (r + c) in posDiag or (r - c) in negDiag:
26 | continue
27 |
28 | col.add(c)
29 | posDiag.add(r + c)
30 | negDiag.add(r - c)
31 | board[r][c] = "Q"
32 |
33 | backtrack(r + 1)
34 |
35 | col.remove(c)
36 | posDiag.remove( r + c)
37 | negDiag.remove(r - c)
38 | board[r][c] = "."
39 |
40 | backtrack(0)
41 | return res
42 |
43 |
44 | class TestSolution(unittest.TestCase):
45 | def test_solveNQueens(self):
46 | self.assertEqual(Solution.solveNQueens(self, 4), [[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]])
47 | self.assertEqual(Solution.solveNQueens(self, 1), [["Q"]])
48 |
49 |
50 | if __name__ == "__main__":
51 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/hard/nQueensII.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/n-queens-ii/
6 | 0(2 ^ N) - TC | 0(N ^ 2) - SC
7 | '''
8 | class Solution:
9 | def solveNQueens(self, n: int) -> List[List[str]]:
10 | col = set()
11 | posDiag = set()
12 | negDiag = set()
13 |
14 | res = []
15 | board = [["."] * n for i in range(n)]
16 |
17 | def backtrack(r):
18 | if r == n:
19 | copy = ["".join(row) for row in board]
20 | res.append(copy)
21 | return
22 |
23 | for c in range(n):
24 | if c in col or (r + c) in posDiag or (r - c) in negDiag:
25 | continue
26 |
27 | col.add(c)
28 | posDiag.add(r + c)
29 | negDiag.add(r - c)
30 | board[r][c] = "Q"
31 |
32 | backtrack(r + 1)
33 |
34 | col.remove(c)
35 | posDiag.remove( r + c)
36 | negDiag.remove(r - c)
37 | board[r][c] = "."
38 |
39 | backtrack(0)
40 | return len(res)
41 |
42 |
43 | class TestSolution(unittest.TestCase):
44 | def test_solveNQueens(self):
45 | self.assertEqual(Solution.solveNQueens(self, 4), 2)
46 | self.assertEqual(Solution.solveNQueens(self, 1), 1)
47 |
48 |
49 | if __name__ == "__main__":
50 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/hard/trapWater.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/trapping-rain-water/
6 | 0(n) - tc & 0(1) - sc
7 | '''
8 |
9 | def trap(height:List[int]) -> int:
10 | if not height: return 0
11 |
12 | l, r = 0, len(height) - 1
13 | leftMax, rightMax = height[l], height[r]
14 | res = 0
15 |
16 | while l < r:
17 | if leftMax <= rightMax:
18 | l += 1
19 | leftMax = max(leftMax, height[l])
20 | res += leftMax - height[l]
21 | else:
22 | r -= 1
23 | rightMax = max(rightMax, height[r])
24 | res += rightMax - height[r]
25 |
26 | return res
27 |
28 | class Test(unittest.TestCase):
29 | def test_trap(self):
30 | self.assertEqual(trap([]), 0)
31 | self.assertEqual(trap([0,1,0,2,1,0,1,3,2,1,2,1]), 6)
32 | self.assertEqual(trap([4,2,0,3,2,5]), 9)
33 |
34 | if __name__ == "__main__":
35 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/linked-list/mergeLists.py:
--------------------------------------------------------------------------------
1 | # Definition for singly-linked list.
2 | from typing import Optional
3 |
4 |
5 | class ListNode:
6 | def __init__(self, val=0, next=None):
7 | self.val = val
8 | self.next = next
9 |
10 | '''
11 | https://leetcode.com/problems/merge-two-sorted-lists/
12 | 0(n) - tc | 0(n) - sc
13 | '''
14 |
15 | class Solution:
16 | def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
17 | dummy = ListNode()
18 | tail = dummy
19 |
20 | while True:
21 | if not list1:
22 | tail.next = list2
23 | break
24 | elif not list2:
25 | tail.next = list1
26 | break
27 | elif list1.val <= list2.val:
28 | tail.next = list1
29 | list1 = list1.next
30 | else:
31 | tail.next = list2
32 | list2 = list2.next
33 | tail = tail.next
34 | return dummy.next
35 |
--------------------------------------------------------------------------------
/leetcode/python/linked-list/reverseLList.py:
--------------------------------------------------------------------------------
1 | # Definition for singly-linked list.
2 | from typing import Optional
3 |
4 |
5 | class ListNode:
6 | def __init__(self, val=0, next=None):
7 | self.val = val
8 | self.next = next
9 |
10 |
11 | '''
12 | https://leetcode.com/problems/reverse-linked-list
13 | '''
14 |
15 |
16 | class Solution:
17 | # 0(n) - tc | 0(n) - sc
18 | def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
19 | def reverse(curr, prev):
20 | if curr is None:
21 | return prev
22 | else:
23 | nxt = curr.next
24 | curr.next = prev
25 | return reverse(nxt, curr)
26 | return reverse(head, None)
27 |
28 | # iterative 0(n) - tc | 0(1) - sc
29 | def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
30 | prev, curr = None, head
31 | while curr:
32 | temp = curr.next
33 | curr.next = prev
34 | prev = curr
35 | curr = temp
36 | return prev
37 |
--------------------------------------------------------------------------------
/leetcode/python/medium/characterReplacement.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/longest-repeating-character-replacement/
5 | 0(n) - tc & 0(n) - sc
6 | '''
7 |
8 | def characterReplacement(s:str, k:int) -> int:
9 | l, res = 0, 0
10 | count = {}
11 |
12 | for r in range(len(s)):
13 | count[s[r]] = 1 + count.get(s[r], 0)
14 | while (r - l + 1) - max(count.values()) > k:
15 | count[s[l]] -= 1
16 | l += 1
17 | res = max(res, r - l + 1)
18 | return res
19 |
20 | class Test(unittest.TestCase):
21 | def test_characterReplacement(self):
22 | self.assertEqual(characterReplacement('ABAB', 2), 4)
23 | self.assertEqual(characterReplacement('AABABBA', 1), 4)
24 |
25 | if __name__ == "__main__":
26 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/combinationSum.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | """
5 | https://leetcode.com/problems/combination-sum/
6 | """
7 |
8 | class Solution:
9 | def combinationSum(self, candidates:List[int], target:int) -> List[List[int]]:
10 | res = []
11 |
12 | def dfs(i, cur, total):
13 | if total == target:
14 | res.append(cur.copy())
15 | return
16 |
17 | if i >= len(candidates) or total > target:
18 | return
19 |
20 | cur.append(candidates[i])
21 | dfs(i, cur, total + candidates[i])
22 | cur.pop()
23 | dfs(i + 1, cur, total)
24 |
25 | dfs(0, [], 0)
26 | return res
27 |
28 |
29 | class TestCombination(unittest.TestCase):
30 | def test_combinationSum(self):
31 | one = Solution.combinationSum(self, [2,3,6,7], 7)
32 | two = Solution.combinationSum(self, [2,3,5], 8)
33 | three = Solution.combinationSum(self, [2], 1)
34 |
35 | self.assertEqual(one, [[2,2,3],[7]])
36 | self.assertEqual(two, [[2,2,2,2],[2,3,3],[3,5]])
37 | self.assertEqual(three, [])
38 |
39 | if __name__ == "__main__":
40 | unittest.main()
41 |
--------------------------------------------------------------------------------
/leetcode/python/medium/encodeDecode.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | """
5 | https://leetcode.com/problems/encode-and-decode-strings/
6 | """
7 |
8 | class Solution:
9 | """
10 | @param: list of strings
11 | @return: encode string of list to a single string
12 | 0(n) - tc | o(1) - sc
13 | """
14 |
15 | def encode(self, strs:List[str]) -> str:
16 | res = ""
17 | for s in strs:
18 | res += str(len(s)) + "#" + s
19 | return res
20 |
21 | """
22 | @param: string
23 | @return: decides a single string to a list of strings
24 | 0(n) - tc | o(1) - sc
25 | """
26 |
27 | def decode(self, str:str) -> List[str]:
28 | res, i = [], 0
29 |
30 | while i < len(str):
31 | j = i
32 | while str[j] != '#':
33 | j += 1
34 | length = int(str[i:j])
35 | res.append(str[j + 1: j + 1 + length])
36 | i = j + 1 + length
37 |
38 | return res
39 |
40 | class Test(unittest.TestCase):
41 | def test_solution(self):
42 | self.assertEqual(Solution.encode(self, ["Church", "go"]), "6#Church2#go")
43 | self.assertEqual(Solution.decode(self, "6#Church2#go"), ["Church", "go"])
44 |
45 | if __name__ == "__main__":
46 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/houseRobber.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/house-robber/
6 | 0(n) - tc | 0(n) - sc
7 | '''
8 |
9 | def rob(nums:List[int]) -> int:
10 | rob1, rob2 = 0, 0
11 |
12 | for n in nums:
13 | temp = max(n + rob1, rob2)
14 | rob1 = rob2
15 | rob2 = temp
16 | return rob2
17 |
18 | class Test(unittest.TestCase):
19 | def test_rob(self):
20 | self.assertEqual(rob([1, 2, 3, 1]), 4)
21 | self.assertEqual(rob([1, 2]), 2)
22 | self.assertEqual(rob([2, 7, 9, 3, 1]), 12)
23 |
24 | if __name__ == "__main__":
25 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/houseRobberII.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/house-robber/
6 | 0(n) - tc | 0(n) - sc
7 | '''
8 |
9 | class Solution:
10 | def rob(self, nums: List[int]) -> int:
11 | def helper(nums):
12 | rob1, rob2 = 0, 0
13 |
14 | for n in nums:
15 | newRob = max(rob1 + n, rob2)
16 | rob1 = rob2
17 | rob2 = newRob
18 | return rob2
19 | return max(nums[0], helper(nums[1:]), helper(nums[:-1]))
20 |
21 |
22 | class Test(unittest.TestCase):
23 | def test_rob(self):
24 | self.assertEqual(Solution.rob(self, [2, 3, 2]), 3)
25 | self.assertEqual(Solution.rob(self, [1, 2, 3]), 3)
26 | self.assertEqual(Solution.rob(self, [1, 2, 3, 1]), 4)
27 |
28 |
29 | if __name__ == "__main__":
30 | unittest.main()
31 |
--------------------------------------------------------------------------------
/leetcode/python/medium/lengthOfLongestSubstring.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/longest-substring-without-repeating-characters/
5 | 0(n) - TC | 0(n) - SC
6 | '''
7 |
8 | def lengthOfLongestSubstring(s:str) -> int:
9 | l, res, charSet = 0, 0, set()
10 |
11 | for r in range(len(s)):
12 | while s[r] in charSet:
13 | charSet.remove(s[l])
14 | l += 1
15 | charSet.add(s[r])
16 | res = max(res, r - l + 1)
17 |
18 | return res
19 |
20 | #solution 2
21 |
22 | def lengthOfLongestSubstring(s):
23 | res, count, hash = 0, 0, set()
24 |
25 | for i in range(len(s)):
26 | while s[i] in hash:
27 | hash.pop()
28 | count -= 1
29 |
30 | hash.add(s[i])
31 | count += 1
32 | res = max(count, res)
33 |
34 | return res
35 |
36 | class Test(unittest.TestCase):
37 | def test_solution(self):
38 | self.assertEqual(lengthOfLongestSubstring(""), 0)
39 | self.assertEqual(lengthOfLongestSubstring(" "), 1)
40 | self.assertEqual(lengthOfLongestSubstring("dvdf"), 3)
41 |
42 | if __name__ == "__main__":
43 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/longestCommonSubsequence.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/longest-common-subsequence/
5 | 0(mn) - tc | 0(mn) - sc
6 | '''
7 |
8 | class Solution:
9 | def longestCommonSubsequence(self, text1: str, text2: str) -> int:
10 | dp = [[0 for j in range(len(text2) + 1)] for i in range(len(text1) + 1)]
11 |
12 | for i in range(len(text1) -1, -1, -1):
13 | for j in range(len(text2) -1, -1, -1):
14 | if text1[i] == text2[j]:
15 | dp[i][j] = 1 + dp[i + 1][j + 1]
16 | else:
17 | dp[i][j] = max(dp[i][j + 1], dp[i + 1][j])
18 | return dp[0][0]
19 |
20 |
21 | class Test(unittest.TestCase):
22 | def test_lcs(self):
23 | self.assertEqual(Solution.longestCommonSubsequence(self, 'abcde', 'ace'), 3)
24 | self.assertEqual(Solution.longestCommonSubsequence(self, 'abc', 'abc'), 3)
25 | self.assertEqual(Solution.longestCommonSubsequence(self, 'abc', 'def'), 0)
26 | self.assertEqual(Solution.longestCommonSubsequence(self, 'abc', ''), 0)
27 | self.assertEqual(Solution.longestCommonSubsequence(self, '', 'def'), 0)
28 | self.assertEqual(Solution.longestCommonSubsequence(self, '', ''), 0)
29 | self.assertEqual(Solution.longestCommonSubsequence(self, ' ', ' '), 1)
30 |
31 | if __name__ == "__main__":
32 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/longestConsecutiveSequence.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/longest-consecutive-sequence/
6 | 0(n) tc & sc
7 | '''
8 |
9 | def consecutiveSeq(nums:List[int]) -> int:
10 | numsSet = set(nums)
11 | longest = 0
12 |
13 | for n in nums:
14 | if (n - 1) not in numsSet:
15 | length = 0
16 | while (n + length) in numsSet:
17 | length += 1
18 | longest = max(longest, length)
19 |
20 | return longest
21 |
22 | class Test(unittest.TestCase):
23 | def test_consecutiveSeq(self):
24 | self.assertEqual(consecutiveSeq([100,4,200,1,3,2]), 4)
25 | self.assertEqual(consecutiveSeq([0,3,7,2,5,8,4,6,0,1]), 9)
26 |
27 |
28 | if __name__ == "__main__":
29 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/longestPalindromicString.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/longest-palindromic-substring/
5 | 0(n) - tc | 0(1) - sc
6 | '''
7 |
8 | class Solution:
9 | def longestPalindrome(self, s: str) -> str:
10 | res = ""
11 | resLen = 0
12 |
13 | for i in range(len(s)):
14 | # odd length
15 | l, r = i, i
16 |
17 | while l >= 0 and r < len(s) and s[l] == s[r]:
18 | if (r - l + 1) > resLen:
19 | res = s[l:r+1]
20 | resLen = r - l + 1
21 | l -= 1
22 | r += 1
23 |
24 | # even length
25 | l, r = i, i + 1
26 | while l >= 0 and r < len(s) and s[l] == s[r]:
27 | if(r - l + 1) > resLen:
28 | res = s[l:r+1]
29 | resLen = r - l + 1
30 | l -= 1
31 | r += 1
32 | return res
33 |
34 | class Test(unittest.TestCase):
35 | def test_longestPalindrome(self):
36 | self.assertEqual(Solution.longestPalindrome(self, 'babad'), 'bab')
37 | self.assertEqual(Solution.longestPalindrome(self, 'cbbd'), 'bb')
38 | self.assertEqual(Solution.longestPalindrome(self, 'b'), 'b')
39 |
40 | if __name__ == "__main__":
41 | unittest.main()
42 |
--------------------------------------------------------------------------------
/leetcode/python/medium/maxArea.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/container-with-most-water/
6 | 0(n) - tc | 0(1) - sc
7 | '''
8 |
9 | def maxArea(height:List[int]) -> int:
10 | res, l, r = 0, 0, len(height) - 1
11 |
12 | while l < r:
13 | res = max(res, (r - l) * min(height[l], height[r]))
14 | if height[l] <= height[r]:
15 | l += 1
16 | else:
17 | r -= 1
18 |
19 | return res
20 |
21 | class Test(unittest.TestCase):
22 | def test_maxArea(self):
23 | self.assertEqual(maxArea([1,8,6,2,5,4,8,3,7]), 49)
24 | self.assertEqual(maxArea([1,1]), 1)
25 | self.assertEqual(maxArea([5,4,8,3,7]), 20)
26 |
27 |
28 | if __name__ == "__main__":
29 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/maxAreaIslands.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | class Solution:
5 | def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
6 | ROWS, COLS = len(grid), len(grid[0])
7 | visited = set()
8 |
9 | def dfs(r, c):
10 | if (r < 0 or r == ROWS or c < 0 or c == COLS or grid[r][c] == 0 or (r, c) in visited):
11 | return 0
12 | visited.add((r, c))
13 | return 1 + dfs(r + 1, c) + dfs(r - 1, c) + dfs(r, c + 1) + dfs(r, c - 1)
14 |
15 | area = 0
16 |
17 | for r in range(ROWS):
18 | for c in range(COLS):
19 | area = max(area, dfs(r, c))
20 | return area
21 |
22 | grid_one= [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]]
23 | grid_two = [[0,0,0,0,0,0,0,0]]
24 |
25 | class Test(unittest.TestCase):
26 | def test_maxAreaOfIslands(self):
27 | self.assertEqual(Solution.maxAreaOfIsland(self, grid_one), 6)
28 | self.assertEqual(Solution.maxAreaOfIsland(self, grid_two), 0)
29 |
30 | if __name__ == "__main__":
31 | unittest.main()
32 |
--------------------------------------------------------------------------------
/leetcode/python/medium/maxProfitCooldown.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/
6 | 0(n) - tc | 0(n) - sc
7 | '''
8 |
9 | class Solution:
10 | def maxProfit(self, prices: List[int]) -> int:
11 | dp = {}
12 |
13 | def dfs(i, canBuy):
14 | if i >= len(prices):
15 | return 0
16 | if (i, canBuy) in dp:
17 | return dp[(i, canBuy)]
18 |
19 | if canBuy:
20 | buy = dfs(i + 1, not canBuy) - prices[i]
21 | cooldown = dfs(i + 1, canBuy)
22 | dp[(i, canBuy)] = max(buy, cooldown)
23 | else:
24 | sell = dfs(i + 2, not canBuy) + prices[i]
25 | cooldown = dfs(i + 1, canBuy)
26 | dp[(i, canBuy)] = max(sell, cooldown)
27 | return dp[(i, canBuy)]
28 |
29 | return dfs(0, True)
30 |
31 | class Test(unittest.TestCase):
32 | def test_maxProfit(self):
33 | self.assertEqual(Solution.maxProfit(self, [1,2,3,0,2]), 3)
34 | self.assertEqual(Solution.maxProfit(self, [1]), 0)
35 |
36 | if __name__ == "__main__":
37 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/maxSubArray.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | from typing import List
3 |
4 | '''
5 | https://leetcode.com/problems/maximum-subarray/
6 | 0(n) - tc | 0(1) - sc
7 | '''
8 |
9 | class Solution:
10 | def maxSubArray(self, nums: List[int]) -> int:
11 | res = nums[0]
12 | currSum = 0
13 |
14 | for num in nums:
15 | currSum += num
16 | res = max(res, currSum)
17 | if currSum < 0:
18 | currSum = 0
19 |
20 | return res
21 |
22 |
23 | class Test(unittest.TestCase):
24 | def test_maxSubArray(self):
25 | self.assertEqual(Solution.maxSubArray(self, [-1]), -1)
26 | self.assertEqual(Solution.maxSubArray(self, [1]), 1)
27 | self.assertEqual(Solution.maxSubArray(self, [-2,1,-3,4,-1,2,1,-5,4]), 6)
28 | self.assertEqual(Solution.maxSubArray(self, [5,4,-1,7,8]), 23)
29 |
30 | if __name__ == "__main__":
31 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/maxUniqueSubArray.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/maximum-erasure-value/
6 | 0(n) - tc & sc
7 | '''
8 |
9 | def maximumUniqueSubArray(nums:List[int]) -> int:
10 | l, total, sum = 0, 0, 0
11 | hash = set()
12 |
13 | for r in range(len(nums)):
14 | while nums[r] in hash:
15 | hash.remove(nums[l])
16 | sum -= nums[l]
17 | l += 1
18 |
19 | hash.add(nums[r])
20 | sum += nums[r]
21 | total = max(total, sum)
22 |
23 | return total
24 |
25 |
26 | class Test(unittest.TestCase):
27 | def test_maxUniqueSubArray(self):
28 | self.assertEqual(maximumUniqueSubArray([4,2,4,5,6]), 17)
29 | self.assertEqual(maximumUniqueSubArray([5,2,1,2,5,2,1,2,5]), 8)
30 |
31 |
32 | if __name__ == "__main__":
33 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/minCostClimbingStairs.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/min-cost-climbing-stairs/
6 | 0(n) - tc | 0(n) - sc
7 | '''
8 |
9 | def minCostClimbingStairs(cost:List[List[int]]) -> int:
10 | cost.append(0)
11 | for i in range(len(cost) - 3, -1, -1):
12 | cost[i] += min(cost[i + 1], cost[i + 2])
13 | return min(cost[0], cost[1])
14 |
15 | class Test(unittest.TestCase):
16 | def test_minCostClimbingStairs(self):
17 | self.assertEqual(minCostClimbingStairs([10, 15, 20]), 15)
18 | self.assertEqual(minCostClimbingStairs([1,100,1,1,1,100,1,1,100,1]), 6)
19 |
20 | if __name__ == "__main__":
21 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/minDistance.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/delete-operation-for-two-strings/
5 | 0(m + n) - tc | 0(min(m + n)) - sc
6 | '''
7 |
8 | def minDistance(word1:str, word2:str) -> int:
9 | if len(word1) > len(word2):
10 | word2, word1 = word1, word2
11 |
12 | m, n = len(word1), len(word2)
13 | prev = [0] * (m + 1)
14 |
15 | for i in range(n-1, -1, -1):
16 | curr = [0] * (m + 1)
17 | for j in range(m-1, -1, -1):
18 | if word1[j] == word2[i]:
19 | curr[j] = 1 + prev[j + 1]
20 | else:
21 | curr[j] = max(curr[j + 1], prev[j])
22 | prev = curr
23 |
24 | return m + n - 2 * prev[0]
25 |
26 | class Test(unittest.TestCase):
27 | def test_minDistance(self):
28 | self.assertEqual(minDistance('sea', 'eat'),2)
29 | self.assertEqual(minDistance('sea', 'cap'),0)
30 | self.assertEqual(minDistance('leetcode', 'etco'),4)
31 |
32 | if __name__ == "__main__":
33 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/minOperations.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/minimum-operations-to-reduce-x-to-zero/
6 | 0(n) - tc | 0(1) - sc
7 | '''
8 |
9 | class Solution:
10 | def minOperations(self, nums: List[int], x: int) -> int:
11 | total, n = sum(nums), len(nums)
12 | target = total - x
13 | maxLen = -1
14 | left, currSum = 0, 0
15 |
16 | for right, num in enumerate(nums):
17 | currSum += num
18 |
19 | while currSum > target and left <= right:
20 | currSum -= nums[left]
21 | left += 1
22 |
23 | if currSum == target:
24 | maxLen = max(maxLen, right - left + 1)
25 |
26 | return n - maxLen if maxLen != -1 else - 1
27 |
28 | class Test(unittest.TestCase):
29 | def test_minOperations(self):
30 | self.assertEqual(Solution.minOperations(self, [1,1,4,2,3], 5), 2)
31 | self.assertEqual(Solution.minOperations(self, [5,6,7,8,9], 4), -1)
32 | self.assertEqual(Solution.minOperations(self, [3,2,20,1,1,3], 10), 5)
33 | self.assertEqual(Solution.minOperations(self, [6016,5483,541,4325,8149,3515,7865,2209,9623,9763,4052,6540,2123,2074,765,7520,4941,5290,5868,6150,6006,6077,2856,7826,9119],
34 | 31841), 6)
35 |
36 | if __name__ == "__main__":
37 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/numDecodings.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/decode-ways/
5 | 0(n) - tc | 0(n) - sc
6 | '''
7 |
8 | class Solution:
9 | def numDecodings(self, s: str) -> int:
10 | dp = {len(s): 1}
11 |
12 | def dfs(i):
13 | if i in dp:
14 | return dp[i]
15 | if s[i] == "0":
16 | return 0
17 |
18 | res = dfs(i + 1)
19 | if (i + 1 < len(s) and (s[i] == "1" or s[i] == "2" and s[i + 1] in "0123456")):
20 | res += dfs(i + 2)
21 | dp[i] = res
22 | return res
23 | return dfs(0)
24 |
25 | class Test(unittest.TestCase):
26 | def test_numDecodings(self):
27 | self.assertEqual(Solution.numDecodings(self, "12"), 2)
28 | self.assertEqual(Solution.numDecodings(self, "226"), 3)
29 | self.assertEqual(Solution.numDecodings(self, "06"), 0)
30 |
31 | if __name__ == "__main__":
32 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/palindromicSubstring.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/palindromic-substrings/
5 | 0(n) - tc | 0(1) - sc
6 | '''
7 |
8 | class Solution:
9 | def countSubstrings(self, s: str) -> int:
10 | resLen = 0
11 |
12 | for i in range(len(s)):
13 | l, r = i, i
14 |
15 | while l >= 0 and r < len(s) and s[l] == s[r]:
16 | resLen += 1
17 | l -= 1
18 | r += 1
19 |
20 | # even numbers
21 | l, r = i, i + 1
22 | while l >= 0 and r < len(s) and s[l] == s[r]:
23 | resLen += 1
24 | l -= 1
25 | r += 1
26 | return resLen
27 |
28 | class Test(unittest.TestCase):
29 | def test_countSubstrings(self):
30 | self.assertEqual(Solution.countSubstrings(self, 'abc'), 3)
31 | self.assertEqual(Solution.countSubstrings(self, 'aaa'), 6)
32 | self.assertEqual(Solution.countSubstrings(self, 'aa'), 3)
33 | self.assertEqual(Solution.countSubstrings(self, 'a'), 1)
34 | self.assertEqual(Solution.countSubstrings(self, ''), 0)
35 | self.assertEqual(Solution.countSubstrings(self, ' '), 1)
36 |
37 | if __name__ == "__main__":
38 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/permutation.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | """
5 | https://leetcode.com/problems/permutations/
6 | 0(n) - SC | 0(2^n) - TC
7 | """
8 |
9 | def permute(nums:List[int]) -> List[List[int]]:
10 | res = []
11 |
12 | if (len(nums)) == 1:
13 | return [nums[:]]
14 |
15 | for i in range (len(nums)):
16 | n = nums.pop(0)
17 | perms = permute(nums)
18 |
19 | for perm in perms:
20 | perm.append(n)
21 |
22 | res.extend(perms)
23 | nums.append(n)
24 |
25 | return res
26 |
27 | class TestPermutation(unittest.TestCase):
28 | def test_permute(self):
29 | one = permute([1,2,3])
30 | two = permute([1])
31 | three = permute([0, 1])
32 |
33 | self.assertEqual(one, [[3, 2, 1], [2, 3, 1], [1, 3, 2], [3, 1, 2], [2, 1, 3], [1, 2, 3]])
34 | self.assertEqual(two, [[1]])
35 | self.assertEqual(three, [[1, 0], [0, 1]])
36 |
37 | if __name__ == "__main__":
38 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/productExceptSelf.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/product-of-array-except-self/
6 | 0(n) - TC | 0(1) - SC (the output array does not count as extra space)
7 | '''
8 |
9 | def productExceptSelf(nums:List[int]) -> List[int]:
10 | res = [1] * len(nums)
11 | prefix = 1
12 |
13 | for i in range (len(nums)):
14 | res[i] = prefix
15 | prefix *= nums[i]
16 |
17 | postfix = 1
18 |
19 | for i in range(len(nums) - 1, -1, -1):
20 | res[i] *= postfix
21 | postfix *= nums[i]
22 |
23 | return res
24 |
25 |
26 | class Test(unittest.TestCase):
27 | def test_productExceptSelf(self):
28 | self.assertEqual(productExceptSelf([1,2,3,4]), [24, 12, 8, 6])
29 | self.assertEqual(productExceptSelf([-1,1,0,-3,3]), [0, 0, 9, 0, 0])
30 |
31 |
32 | if __name__ == "__main__":
33 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/rangeSumQuery.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | """
3 | https://leetcode.com/problems/range-sum-query-2d-immutable/
4 | """
5 |
6 | class NumMatrix:
7 |
8 | def __init__(self, matrix: List[List[int]]):
9 | rows, cols = len(matrix), len(matrix[0])
10 | self.sumMath = [[0] * (cols + 1) for r in range (rows + 1)]
11 |
12 | for r in range(rows):
13 | prefix = 0
14 | for c in range(cols):
15 | prefix += matrix[r][c]
16 | above = self.sumMath[r][c + 1]
17 | self.sumMath[r + 1][c + 1] = prefix + above
18 |
19 |
20 | def sumRegion(self, r1: int, c1: int, r2: int, c2: int) -> int:
21 | r1, c1, r2, c2 = r1 + 1, c1 + 1, r2 + 1, c2 + 1
22 |
23 | bottomRight = self.sumMath[r2][c2]
24 | above = self.sumMath[r1 - 1][c2]
25 | left = self.sumMath[r2][c1 - 1]
26 | topLeft = self.sumMath[r1 - 1][c1 - 1]
27 |
28 | return bottomRight - above - left + topLeft
29 |
--------------------------------------------------------------------------------
/leetcode/python/medium/subsets-ii.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | def subsetsWithDup(nums:List[int]) -> List[List[int]]:
5 | res, subset = [], []
6 |
7 | def backtrack(i):
8 | if i >= len(nums):
9 | res.append(subset[::])
10 | return
11 |
12 | subset.append(nums[i])
13 | backtrack(i + 1)
14 | subset.pop()
15 |
16 | while i + 1 < len(nums) and nums[i] == nums [i + 1]:
17 | i += 1
18 |
19 | backtrack(i + 1)
20 |
21 | backtrack(0)
22 | return res
23 |
24 | class Test(unittest.TestCase):
25 | def test_subsetWithDup(self):
26 | self.assertEqual(subsetsWithDup([1, 2, 2]), [[1, 2, 2], [1, 2], [1], [2, 2], [2], []])
27 | self.assertEqual(subsetsWithDup([0]), [[0], []])
28 |
29 | if __name__ == "__main__":
30 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/subsets.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/subsets/
6 | 0(n * 2^n) - TC | 0(n) - SC
7 | '''
8 |
9 | def subsets(nums: List[int]) -> List[List[int]]:
10 | res, subset = [], []
11 |
12 | def backtrack(i):
13 | if i >= len(nums):
14 | res.append(subset[::])
15 | return
16 |
17 | subset.append(nums[i])
18 | backtrack(i + 1)
19 |
20 | subset.pop()
21 | backtrack(i + 1)
22 |
23 | backtrack(0)
24 | return res
25 |
26 | class Test(unittest.TestCase):
27 | def test_subset(self):
28 | self.assertEqual(subsets([1, 2, 3]), [[1, 2, 3], [1, 2], [1, 3], [1], [2, 3], [2], [3], []])
29 | self.assertEqual(subsets([1]), [[1], []])
30 |
31 |
32 | if __name__ == '__main__':
33 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/test_KClosest.py:
--------------------------------------------------------------------------------
1 | import heapq
2 | from typing import List
3 | import unittest
4 |
5 | """
6 | https://leetcode.com/problems/k-closest-points-to-origin/
7 | 0(k log n) - TC | 0(n) - SC
8 | """
9 |
10 | class Solution:
11 | def KClosest(self, points:List[List[int]], k:int) -> List[List[int]]:
12 | minHeap = []
13 |
14 | for x,y in points:
15 | dist = (x**2) + (y**2)
16 | minHeap.append([dist, x, y])
17 |
18 | heapq.heapify(minHeap)
19 | res = []
20 |
21 | while k > 0:
22 | dist, x, y = heapq.heappop(minHeap)
23 | res.append([x,y])
24 | k -= 1
25 |
26 | return res
27 |
28 | class TestKClosest(unittest.TestCase):
29 | def test_KClosest(self):
30 | points = [[1,3],[-2,2]]
31 | points_two = [[3,3],[5,-1],[-2,4]]
32 | k = 1
33 | k_two = 2
34 | result = Solution.KClosest(self, points, k)
35 | result_two = Solution.KClosest(self, points_two, k_two)
36 | self.assertEqual(result, [[-2, 2]])
37 | self.assertEqual(result_two, [[3,3],[-2,4]])
38 |
39 | if __name__ == '__main__':
40 | unittest.main()
41 |
--------------------------------------------------------------------------------
/leetcode/python/medium/test_KthLargestArr.py:
--------------------------------------------------------------------------------
1 | import heapq
2 | from typing import List
3 | import unittest
4 |
5 | """
6 | https://leetcode.com/problems/kth-largest-element-in-an-array/
7 | """
8 | class Solution:
9 | """
10 | sort method
11 | 0(n log n) - TC | 0(n) - SC
12 | """
13 | def KthLargestArr(self, nums: List[int], k: int) -> int:
14 | nums.sort()
15 | idx = len(nums) - k
16 | return nums[idx]
17 |
18 | """
19 | Heap method
20 | 0(k log n) - TC | 0(1) - SC
21 | """
22 | def KthLargestHeap(self, nums: List[int], k: int) -> int:
23 | heapq.heapify(nums)
24 | while len(nums) > k:
25 | heapq.heappop(nums)
26 | return nums[0]
27 |
28 |
29 | class TestKthLargestArr(unittest.TestCase):
30 | def test_kthLargest(self):
31 | nums = [3, 2, 3, 1, 2, 4, 5, 5, 6]
32 | res = Solution.KthLargestArr(self, nums, 4)
33 | res_two = Solution.KthLargestHeap(self, [3, 2, 1, 5, 6, 4], 2)
34 | self.assertEqual(res, 4)
35 | self.assertEqual(res_two, 5)
36 |
37 |
38 | if __name__ == "__main__":
39 | unittest.main()
40 |
--------------------------------------------------------------------------------
/leetcode/python/medium/topKFrequent.py:
--------------------------------------------------------------------------------
1 | import heapq
2 | from typing import List
3 | import unittest
4 |
5 | """
6 | https://leetcode.com/problems/top-k-frequent-elements/
7 | """
8 |
9 | class Solution:
10 | """
11 | Heap method
12 | 0(k log n) - TC | 0(n) - SC
13 | """
14 | def topKFrequent(self, nums: List[int], k: int) -> List[int]:
15 | count = {}
16 | minHeap = []
17 | res = []
18 |
19 | # Count each number in the nums array
20 | for n in nums:
21 | count[n] = 1 + count.get(n, 0)
22 |
23 | # Add the (num, count to the heap)
24 | for n, c in count.items():
25 | heapq.heappush(minHeap, (c, n))
26 | if len(minHeap) > k:
27 | heapq.heappop(minHeap)
28 |
29 | # append the numbers with k occurence to res
30 | for c, n in minHeap:
31 | res.append(n)
32 |
33 | return res
34 |
35 | """
36 | Bucket sort
37 | 0(n) - TC | 0(n) - SC
38 | """
39 |
40 | def topKFrequentBucket(self, nums:List[int], k:int) -> List[int]:
41 | count = {}
42 | freq = [[] for i in range (len (nums) + 1)]
43 |
44 | for n in nums:
45 | count[n] = 1 + count.get(n, 0)
46 |
47 | for n, c in count.items():
48 | freq[c].append(n)
49 |
50 | res = []
51 | for i in range(len(freq) -1, 0, -1):
52 | for n in freq[i]:
53 | res.append(n)
54 | if len(res) == k:
55 | return res
56 |
57 |
58 | class TestTopK(unittest.TestCase):
59 | def test_topK(self):
60 | data = Solution.topKFrequent(self, [5,5,5,5,6,6,6,7], 2)
61 | self.assertEqual(data, [6,5])
62 |
63 | def test_topKBucket(self):
64 | data = Solution.topKFrequentBucket(self, [2,2,2,3,3], 1)
65 | self.assertEqual(data, [2])
66 |
67 | if __name__ == "__main__":
68 | unittest.main()
69 |
--------------------------------------------------------------------------------
/leetcode/python/medium/triangle.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/triangle/
6 | 0(n) - sc | 0(2 ^ n) - tc
7 | '''
8 |
9 | def minTotal(triangle:List[List[int]]) -> int:
10 | dp = [0] * (len(triangle) + 1)
11 |
12 | for row in triangle[::-1]:
13 | for i, n in enumerate(row):
14 | dp[i] = n + min(dp[i], dp[i + 1])
15 |
16 | return dp[0]
17 |
18 |
19 | class Test(unittest.TestCase):
20 | def test_minTotal(self):
21 | self.assertEqual(minTotal([[-1],[2,3],[1,-1,-3]]), -1)
22 | self.assertEqual(minTotal([[2],[3,4],[6,5,7],[4,1,8,3]]), 11)
23 | self.assertEqual(minTotal([[-10]]), -10)
24 |
25 | if __name__ == "__main__":
26 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/twoSumII.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | def TwoSumII(nums, target) -> List[int]:
5 | i, j = 0, len(nums) - 1
6 |
7 | while i < j:
8 | sum = nums[i] + nums[j]
9 |
10 | if sum == target:
11 | return [i + 1, j + 1]
12 | elif sum < target:
13 | i += 1
14 | else:
15 | j -= 1
16 |
17 |
18 | class Test(unittest.TestCase):
19 | def test_TwoSumII(self):
20 | self.assertEqual(TwoSumII([2,3,5,7,11], 9), [1, 4])
21 | self.assertEqual(TwoSumII([0, -1], -1), [1, 2])
22 |
23 |
24 | if __name__ == "__main__":
25 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/python/medium/uniquePaths.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | '''
4 | https://leetcode.com/problems/unique-paths/
5 | 0(m * n) - tc | 0(m + n) - sc
6 | '''
7 |
8 | def uniquePaths(m: int, n: int) -> int:
9 | def memoPath(m, n, memo={}):
10 | key = (m, n)
11 | if key in memo:
12 | return memo[key]
13 | if m == 1 and n == 1:
14 | return 1
15 | if m == 0 or n == 0:
16 | return 0
17 |
18 | memo[key] = (memoPath(m - 1, n) + memoPath(m, n - 1))
19 | return memo[key]
20 |
21 | return memoPath(m, n)
22 |
23 |
24 | class Test(unittest.TestCase):
25 | def test_uniquePaths(self):
26 | self.assertEqual(uniquePaths(3,7), 28)
27 | self.assertEqual(uniquePaths(2,3), 3)
28 | self.assertEqual(uniquePaths(3, 3), 6)
29 | self.assertEqual(uniquePaths(18, 18), 2333606220 )
30 |
31 | if __name__ == "__main__":
32 | unittest.main()
33 |
34 |
--------------------------------------------------------------------------------
/leetcode/python/test_sum.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | def my_sum(nums):
4 | total = 0
5 | for n in nums:
6 | total += n
7 | return total
8 |
9 | class TestSum(unittest.TestCase):
10 | def test_sum(self):
11 | """
12 | test that the sum of the list is correct
13 | """
14 | data = [1,2,3]
15 | result = my_sum(data)
16 | self.assertEqual(result, 6, "should be 6")
17 |
18 | def test_sum_input(self):
19 | """
20 | test that the input is truthy
21 | """
22 | data = [2,4,6]
23 | result = my_sum(data)
24 | self.assertTrue(result)
25 |
26 | if __name__ == "__main__":
27 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/sean-prashad/Javascript/15-binarySearch.test.js:
--------------------------------------------------------------------------------
1 | // https://leetcode.com/problems/binary-search/
2 | // Test: npm test ./sean-prashad/Javascript/15-binarySearch.test.js
3 | // 0(log n) - time | 0(1) - space
4 |
5 | describe('#binary search', () => {
6 | it('returns the index of a given target', () => {
7 | expect(binarySearch([1, 0, 3, 5, 9, 12], 9)).toBe(4)
8 | expect(binarySearch([1, 0, 3, 5, 9, 12], 2)).toBe(-1)
9 | expect(binarySearch([1], 2)).toBe(-1)
10 | })
11 | })
12 |
13 |
14 | const binarySearch = (nums, target) => {
15 | let lower = 0
16 | let upper = nums.length - 1
17 |
18 | while (lower <= upper) {
19 | let mid = Math.floor((upper + lower) / 2)
20 |
21 | if (target === nums[mid]) {
22 | return mid
23 | }
24 |
25 | if (nums[mid] > target) {
26 | upper = mid - 1
27 | } else {
28 | lower = mid + 1
29 | }
30 | }
31 |
32 | return -1
33 | };
--------------------------------------------------------------------------------
/leetcode/sean-prashad/Javascript/16-nextGreatestLetter.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {character[]} letters
3 | * @param {character} target
4 | * @return {character}
5 | */
6 |
7 | // https://leetcode.com/problems/find-smallest-letter-greater-than-target
8 | // Test: npm test ./sean-prashad/Javascript/16-nextGreatestLetter.test.js
9 | // 0(log n) - time | 0(1) - space
10 |
11 | describe('#nextGreatestLetter', () => {
12 | it('returns the Smallest Letter Greater Than Target', () => {
13 | expect(nextGreatestLetter(["c", "f", "j"], "a")).toBe("c")
14 | expect(nextGreatestLetter(["c", "f", "j"], "c")).toBe("f")
15 | expect(nextGreatestLetter(["c", "f", "j"], "d")).toBe("f")
16 | expect(nextGreatestLetter(["c", "f", "j"], "j")).toBe("c")
17 | })
18 | })
19 |
20 |
21 |
22 | var nextGreatestLetter = function(letters, target) {
23 | let [left, right] = [0, letters.length - 1]
24 |
25 | if (target < letters[left] || target >= letters[right]){
26 | return letters[0]
27 | }
28 |
29 | while (left < right){
30 | let mid = Math.floor((left + right) / 2)
31 |
32 | if (letters[mid] > target){
33 | right = mid
34 | } else{
35 | left = mid + 1
36 | }
37 | }
38 |
39 | return letters[right]
40 | };
--------------------------------------------------------------------------------
/leetcode/sean-prashad/Javascript/17-avgOfLevels.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * function TreeNode(val, left, right) {
4 | * this.val = (val===undefined ? 0 : val)
5 | * this.left = (left===undefined ? null : left)
6 | * this.right = (right===undefined ? null : right)
7 | * }
8 | */
9 | /**
10 | * @param {TreeNode} root
11 | * @return {number[]}
12 | */
13 |
14 | // 0(n) - TC | 0(N) - SC
15 | var averageOfLevels = function(root) {
16 | let res = []
17 | let queue = [root]
18 |
19 | while(queue.length){
20 | let total = 0
21 | queueLen = queue.length
22 |
23 | for(let i = 0; i < queueLen; i++){
24 | node = queue.shift()
25 | total += node.val
26 |
27 | if(node.left) queue.push(node.left)
28 | if(node.right) queue.push(node.right)
29 | }
30 | res.push(total / queueLen)
31 | }
32 | return res
33 | };
--------------------------------------------------------------------------------
/leetcode/sean-prashad/Javascript/18-minDeptht.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * function TreeNode(val, left, right) {
4 | * this.val = (val===undefined ? 0 : val)
5 | * this.left = (left===undefined ? null : left)
6 | * this.right = (right===undefined ? null : right)
7 | * }
8 | */
9 | /**
10 | * @param {TreeNode} root
11 | * @return {number}
12 | */
13 |
14 | var minDepth = function (root) {
15 | if (root == null) return 0
16 |
17 | if (root.right == null && root.left == null) return 1
18 |
19 | if (root.right == null) {
20 | return 1 + minDepth(root.left)
21 | }
22 |
23 | if (root.left == null) {
24 | return 1 + minDepth(root.right)
25 | }
26 |
27 | return 1 + Math.min(minDepth(root.right), minDepth(root.left))
28 | };
--------------------------------------------------------------------------------
/leetcode/sean-prashad/Javascript/19-maxDepth.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * function TreeNode(val, left, right) {
4 | * this.val = (val===undefined ? 0 : val)
5 | * this.left = (left===undefined ? null : left)
6 | * this.right = (right===undefined ? null : right)
7 | * }
8 | */
9 | /**
10 | * @param {TreeNode} root
11 | * @return {number}
12 | */
13 | var maxDepth = function(root) {
14 | if(root == null) return 0
15 |
16 | if (root.left == null && root.right == null) return 1
17 |
18 | if(root.left == null){
19 | return 1 + maxDepth(root.right)
20 | }
21 |
22 | if(root.right == null){
23 | return 1 + maxDepth(root.left)
24 | }
25 |
26 | return 1 + Math.max(maxDepth(root.left), maxDepth(root.right))
27 | };
--------------------------------------------------------------------------------
/leetcode/sean-prashad/Javascript/20-isSameTree.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * function TreeNode(val, left, right) {
4 | * this.val = (val===undefined ? 0 : val)
5 | * this.left = (left===undefined ? null : left)
6 | * this.right = (right===undefined ? null : right)
7 | * }
8 | */
9 | /**
10 | * @param {TreeNode} p
11 | * @param {TreeNode} q
12 | * @return {boolean}
13 | */
14 | // https://leetcode.com/problems/same-tree/
15 | // BFS - O(N) - TC & SC
16 | var isSameTree = function (p, q) {
17 | const queue = [[p, q]]
18 |
19 | while (queue.length) {
20 | const [p, q] = queue.shift()
21 |
22 | if (!p && !q) continue
23 | if (!p || !q) return false
24 | if (p.val !== q.val) return false
25 |
26 | if (p && q) {
27 | queue.push([p.right, q.right])
28 | queue.push([p.left, q.left])
29 | }
30 |
31 | }
32 | return true
33 | };
34 |
35 | // Recursive DFS 0(N) - TC & SC
36 | var isSameTree = function (p, q) {
37 | if (!p && !q) return true
38 | if (!p || !q) return false
39 | if (p.val !== q.val) return false
40 |
41 | return isSameTree(p.left, q.left) &&
42 | isSameTree(p.right, q.right)
43 | };
--------------------------------------------------------------------------------
/leetcode/sean-prashad/Javascript/21-pathSum.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * function TreeNode(val, left, right) {
4 | * this.val = (val===undefined ? 0 : val)
5 | * this.left = (left===undefined ? null : left)
6 | * this.right = (right===undefined ? null : right)
7 | * }
8 | */
9 | /**
10 | * @param {TreeNode} root
11 | * @param {number} targetSum
12 | * @return {boolean}
13 | */
14 | var hasPathSum = function(root, sum) {
15 | if(root === null) return false
16 |
17 | if (root.left === null && root.right === null && root.val === sum) return true
18 |
19 | return (hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val))
20 | };
--------------------------------------------------------------------------------
/leetcode/sean-prashad/Javascript/22-twoSum.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} target
4 | * @return {number[]}
5 | */
6 |
7 | // npm test ./leetcode/sean-prashad/javascript/22-twoSum.test.js",
8 | // https://leetcode.com/problems/two-sum/
9 | // 0(n) - time | 0(n) - space
10 |
11 | const twoSum = function (nums, target) {
12 | let hash = {}
13 |
14 | for (let i = 0; i <= nums.length; i++) {
15 | let diff = target - nums[i]
16 |
17 | if (diff in hash) return [i, hash[diff]]
18 | hash[nums[i]] = i
19 | }
20 | }
21 |
22 | describe('#Two Sum', () => {
23 | it('returns the indices of values that sum up to a target', () => {
24 | expect(twoSum([2, 7, 11, 15], 9)).toStrictEqual([1, 0])
25 | expect(twoSum([3, 2, 4], 6)).toStrictEqual([2, 1])
26 | expect(twoSum([3, 3], 6)).toStrictEqual([1, 0])
27 | })
28 | })
29 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/Javascript/23-invertBinaryTree.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * function TreeNode(val, left, right) {
4 | * this.val = (val===undefined ? 0 : val)
5 | * this.left = (left===undefined ? null : left)
6 | * this.right = (right===undefined ? null : right)
7 | * }
8 | */
9 | /**
10 | * @param {TreeNode} root
11 | * @return {TreeNode}
12 | */
13 |
14 | // 0(n) - time | 0(n) - space
15 | // https://leetcode.com/problems/invert-binary-tree/
16 |
17 | const invertTree = function(root) {
18 | if(!root) return root
19 |
20 | let temp = root.left
21 | root.left = root.right
22 | root.right = temp
23 |
24 | invertTree(root.right)
25 | invertTree(root.left)
26 |
27 | return root
28 | };
--------------------------------------------------------------------------------
/leetcode/sean-prashad/Javascript/24-subTree.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * function TreeNode(val, left, right) {
4 | * this.val = (val===undefined ? 0 : val)
5 | * this.left = (left===undefined ? null : left)
6 | * this.right = (right===undefined ? null : right)
7 | * }
8 | */
9 | /**
10 | * @param {TreeNode} root
11 | * @param {TreeNode} subRoot
12 | * @return {boolean}
13 | */
14 |
15 | // https://leetcode.com/problems/subtree-of-another-tree/
16 | // 0(r * s) - tc | 0(r * s) - sc
17 |
18 |
19 | var isSubtree = function(root, subRoot) {
20 | if (subRoot && !root) return false
21 |
22 | if (isMatch(root, subRoot)) return true
23 |
24 | return (isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot))
25 |
26 | };
27 |
28 | const isMatch = function(r, s){
29 | if (r && s) {
30 | return (r.val === s.val && isMatch(r.left, s.left) && isMatch(r.right, s.right))
31 | }
32 | if(!r && s) return false
33 | if(r && !s) return false
34 | if(!r && !s) return true
35 | }
--------------------------------------------------------------------------------
/leetcode/sean-prashad/Javascript/25-squareSortedArr.test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number[]}
4 | */
5 |
6 | // https://leetcode.com/problems/squares-of-a-sorted-array/
7 | // 0(n) - tc | 0(n) - sc
8 |
9 |
10 | const sortedSquares = function(nums) {
11 | let res = []
12 | let [l, r] = [0, nums.length - 1]
13 |
14 | while (l <= r){
15 | let [left, right] = [nums[l], nums[r]]
16 |
17 | if (Math.abs(right) > Math.abs(left)){
18 | res.unshift(right * right)
19 | r--
20 | } else{
21 | res.unshift(left * left)
22 | l++
23 | }
24 | }
25 | return res
26 | };
27 |
28 | describe('#Squares of sorted Array', () => {
29 | it('returns the sorted value of the values in the array', () => {
30 | expect(sortedSquares([-4,-1,0,3,10])).toStrictEqual( [0,1,9,16,100])
31 | expect(sortedSquares([-7,-3,2,3,11])).toStrictEqual([4,9,9,49,121])
32 | expect(sortedSquares([-4,-1,3,10])).toStrictEqual([1,9,16,100])
33 | expect(sortedSquares([1, 2, 3, 4])).toStrictEqual([1,4,9,16])
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/Javascript/27-majorityElement.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/majority-element
2 |
3 | /**
4 | * @param {number[]} nums
5 | * @return {number}
6 | */
7 |
8 | // 0(n) - TC | 0(n) - SC
9 | const majorityElement = function (nums) {
10 | const map = {}
11 | let [maxCount, res] = [0, 0]
12 |
13 | for (let i = 0; i < nums.length; i++) {
14 | map[nums[i]] = map[nums[i]] + 1 || 1
15 |
16 | if (map[nums[i]] > maxCount) {
17 | res = nums[i]
18 | maxCount = map[nums[i]]
19 | }
20 | }
21 |
22 | return res
23 | };
24 |
25 | const majorityElementBoyer = function (nums) {
26 | let [res, maxCount] = [0, 0]
27 |
28 | for (let num of nums) {
29 | if (maxCount === 0) {
30 | res = num
31 | }
32 |
33 | maxCount += num === res ? 1 : -1
34 | }
35 |
36 | return res
37 | };
38 |
39 | describe('#Majority Element', () => {
40 | describe('it returns the element that occurs more than half the length in the array', () => {
41 |
42 | it('function 1', () => {
43 | expect(majorityElement([2, 2, 1, 1, 1, 2, 2])).toBe(2)
44 | expect(majorityElement([2, 1, 1, 1, 1, 2, 2])).toBe(1)
45 | expect(majorityElement([2, 3, 1, 2, 2, 2, 2])).toBe(2)
46 | })
47 |
48 | it('function 2', () => {
49 | expect(majorityElementBoyer([2, 2, 1, 1, 1, 2, 2])).toBe(2)
50 | expect(majorityElementBoyer([2, 1, 1, 1, 1, 2, 2])).toBe(1)
51 | expect(majorityElementBoyer([2, 3, 1, 2, 2, 2, 2])).toBe(2)
52 | })
53 | })
54 | })
55 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/Javascript/28-productExceptSelf.test.js:
--------------------------------------------------------------------------------
1 | //https://leetcode.com/problems/product-of-array-except-self/
2 |
3 | // brute force
4 | const productExceptSelfB = (nums) => {
5 | const N = nums.length
6 | let prod = new Array(N)
7 |
8 | for (let i = 0; i < N; i++) {
9 | let prodExclCurr = 1
10 |
11 | for (let j = 0; j < N; j++) {
12 | if (i == j) continue
13 |
14 | prodExclCurr *= nums[j]
15 | }
16 | prod[i] = prodExclCurr
17 | }
18 |
19 | return prod
20 | };
21 |
22 | describe('#Product of Array Except Self', () => {
23 | describe('it returns the product of elements in the array except its self', () => {
24 |
25 | test('brute force', () => {
26 | expect(productExceptSelfB([1, 2, 3, 4])).toStrictEqual([24, 12, 8, 6])
27 | // expect(productExceptSelfB([-1, 1, 0, -3, 3])).toStrictEqual([-0, 0, 9, -0, 0])
28 | expect(productExceptSelfB([5, 2, 8, 4, 5])).toStrictEqual([320, 800, 200, 400, 320])
29 | expect(productExceptSelfB([1, 0, 4, 3, 5])).toStrictEqual([0, 60, 0, 0, 0])
30 | expect(productExceptSelfB([1, 1, 1, 1])).toStrictEqual([1, 1, 1, 1])
31 | expect(productExceptSelfB([0, 4, 0, 3])).toStrictEqual([0, 0, 0, 0])
32 | })
33 |
34 |
35 | })
36 | })
37 |
38 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/1-containsDups.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/contains-duplicate/
6 | 0(n) - tc | 0(n) - sc
7 | '''
8 |
9 | class Solution:
10 | def containsDuplicate(self, nums: List[int]) -> bool:
11 | storage = set()
12 |
13 | for num in nums:
14 | if num in storage:
15 | return True
16 | storage.add(num)
17 |
18 | return False
19 |
20 | class Test(unittest.TestCase):
21 | def test_containsDuplicate(self):
22 | self.assertEqual(Solution.containsDuplicate(self, [1,1,1,3,3,4,3,2,4,2]), True)
23 | self.assertEqual(Solution.containsDuplicate(self, [1,1]), True)
24 | self.assertEqual(Solution.containsDuplicate(self, [1,2]), False)
25 | self.assertEqual(Solution.containsDuplicate(self, []), False)
26 | self.assertEqual(Solution.containsDuplicate(self, [1]), False)
27 | self.assertEqual(Solution.containsDuplicate(self, [-1, 2, 3, 4]), False)
28 | self.assertEqual(Solution.containsDuplicate(self, [-1, 2, 3, -1]), True)
29 |
30 | if __name__ == "__main__":
31 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/10-palindromeLList.py:
--------------------------------------------------------------------------------
1 | '''
2 | https://leetcode.com/problems/palindrome-linked-list/
3 | '''
4 | # Definition for singly-linked list.
5 | class ListNode:
6 | def __init__(self, val=0, next=None):
7 | self.val = val
8 | self.next = next
9 | class Solution:
10 | def isPalindrome(self, head:ListNode) -> bool:
11 | llist = []
12 |
13 | while head:
14 | llist.append(head.val)
15 | head = head.next
16 |
17 | left = 0
18 | right = len(llist) - 1
19 |
20 | while left < right:
21 | # print(llist[left], llist[right])
22 | if llist[left] != llist[right]:
23 | return False
24 | left += 1
25 | right -= 1
26 | return True
27 |
28 |
29 | # 0(n) - tc | 0(n) - sc
30 | class Solution:
31 | def isPalindrome(self, head: ListNode) -> bool:
32 | slow, fast = head, head
33 |
34 | #find the middle of the linked list
35 | while fast and fast.next:
36 | slow = slow.next
37 | fast = fast.next.next
38 |
39 | # reverse the middle of the linked list from the slow pointer
40 | prev = None
41 | while slow:
42 | temp = slow.next
43 | slow.next = prev
44 | prev = slow
45 | slow = temp
46 |
47 | # find palindrom
48 | left, right = head, prev
49 | while right:
50 | if left.val != right.val:
51 | return False
52 | left = left.next
53 | right = right.next
54 |
55 | return True
56 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/11-reverseLList.py:
--------------------------------------------------------------------------------
1 | # Definition for singly-linked list.
2 | from typing import Optional
3 |
4 |
5 | class ListNode:
6 | def __init__(self, val=0, next=None):
7 | self.val = val
8 | self.next = next
9 |
10 |
11 | '''
12 | https://leetcode.com/problems/reverse-linked-list
13 | '''
14 |
15 |
16 | class Solution:
17 | # 0(n) - tc | 0(n) - sc
18 | def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
19 | def reverse(curr, prev):
20 | if curr is None: return prev
21 |
22 | nxt = curr.next
23 | curr.next = prev
24 | return reverse(nxt, curr)
25 | return reverse(head, None)
26 |
27 | # iterative 0(n) - tc | 0(1) - sc
28 | def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
29 | prev, curr = None, head
30 | while curr:
31 | temp = curr.next
32 | curr.next = prev
33 | prev = curr
34 | curr = temp
35 | return prev
36 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/12-removeLListEl.py:
--------------------------------------------------------------------------------
1 | # Definition for singly-linked list.
2 | from typing import Optional
3 |
4 |
5 | class ListNode:
6 | def __init__(self, val=0, next=None):
7 | self.val = val
8 | self.next = next
9 |
10 | class Solution:
11 | # create a dummy node
12 | # update its pointers using prev
13 | # 0(n) - TC | 0(n) - SC
14 | def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
15 | dummy = ListNode(next=head)
16 | prev, curr = dummy, head
17 |
18 | while curr:
19 | nxt = curr.next
20 |
21 | if curr.val == val:
22 | prev.next = nxt
23 | else:
24 | prev = curr
25 |
26 | curr = nxt
27 | return dummy.next
28 |
29 |
30 | # recursive solution - 0(n) - TC | 0(n) - sc
31 | def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
32 | if head is None: return None
33 | nxt = self.removeElements(head.next, val)
34 | if head.val == val:
35 | head = nxt
36 | else:
37 | head.next = nxt
38 | return head
39 |
40 | # solution 1 pointer - 0(n) - tc | 0(n) - sc
41 | def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
42 | dummy = cur = ListNode()
43 | dummy.next = head
44 | while cur.next:
45 | if cur.next.val == val:
46 | cur.next = cur.next.next
47 | else:
48 | cur = cur.next
49 | return dummy.next
50 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/13-removeDupsSortedLList.py:
--------------------------------------------------------------------------------
1 | # Definition for singly-linked list.
2 | class ListNode:
3 | def __init__(self, val=0, next=None):
4 | self.val = val
5 | self.next = next
6 | from typing import Optional
7 |
8 | '''
9 | https://leetcode.com/problems/remove-duplicates-from-sorted-list/
10 | '''
11 |
12 | class Solution:
13 | #0(n) - tc | 0(1) - sc
14 | def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
15 | curr = head
16 |
17 | while curr and curr.next:
18 | if curr.val == curr.next.val:
19 | curr.next = curr.next.next
20 | continue
21 | curr = curr.next
22 |
23 | return head
24 |
25 | # Question: Do you understand the difference between the above method and this?
26 | # 0(n) - tc | 0(1) - sc
27 | def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
28 | curr = head
29 |
30 | while curr:
31 | while curr.next and curr.val == curr.next.val:
32 | curr.next = curr.next.next
33 |
34 | curr = curr.next
35 |
36 | return head
37 |
38 | # two pointer + set method
39 | # 0(n) - tc | 0(1) - sc
40 | def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
41 | if not head: return head
42 | prev, curr = head, head.next
43 | dups = set()
44 | dups.add(prev.val)
45 |
46 | while curr:
47 | if curr.val in dups:
48 | prev.next = curr.next
49 | else:
50 | dups.add(curr.val)
51 | prev = curr
52 |
53 | curr = curr.next
54 |
55 | return head
56 |
57 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/14-mergeTwoSortedList.py:
--------------------------------------------------------------------------------
1 | # Definition for singly-linked list.
2 | from typing import Optional
3 |
4 | '''
5 | https://leetcode.com/problems/merge-two-sorted-lists/submissions/
6 | '''
7 | # 0(m + n) - TC
8 |
9 | class ListNode:
10 | def __init__(self, val=0, next=None):
11 | self.val = val
12 | self.next = next
13 |
14 |
15 | class Solution:
16 | # recursive
17 | # 0(n) - SC
18 | def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
19 | def merge(l1, l2):
20 | if not l1:
21 | return l2
22 | if not l2:
23 | return l1
24 |
25 | if l1.val <= l2.val:
26 | l1.next = merge(l1.next, l2)
27 | return l1
28 | else:
29 | l2.next = merge(l1, l2.next)
30 | return l2
31 | return merge(list1, list2)
32 |
33 | # iterative
34 | # 0(1) - SC
35 | def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
36 | dummy = ListNode()
37 | tail = dummy
38 |
39 | while True:
40 | if not list1:
41 | tail.next = list2
42 | break
43 | elif not list2:
44 | tail.next = list1
45 | break
46 | elif list1.val <= list2.val:
47 | tail.next = list1
48 | list1 = list1.next
49 | else:
50 | tail.next = list2
51 | list2 = list2.next
52 | tail = tail.next
53 | return dummy.next
54 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/15-binarySearch.py:
--------------------------------------------------------------------------------
1 | # https://leetcode.com/problems/binary-search/submissions/
2 | # 0(log n) - TC | 0(1) - SC
3 | from typing import List
4 | import unittest
5 |
6 |
7 | class Solution:
8 | def search(self, nums: List[int], target: int) -> int:
9 | lower, upper = 0, len(nums) - 1
10 |
11 | while lower <= upper:
12 | mid = (upper + lower) // 2
13 | if nums[mid] == target:
14 | return mid
15 | elif nums[mid] > target:
16 | upper = mid - 1
17 | else:
18 | lower = mid + 1
19 |
20 | return -1
21 |
22 | class Test(unittest.TestCase):
23 | def test_search(self):
24 | self.assertEqual(Solution.search(self, [-1,0,3,5,9,12], 9), 4)
25 | self.assertEqual(Solution.search(self, [-1,0,3,5,9,12], 2), -1)
26 |
27 | if __name__ == "__main__":
28 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/16-nextGreatestLetter.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | # https://leetcode.com/problems/find-smallest-letter-greater-than-target
5 | # 0(log n) - TC | 0(1) - SC
6 | class Solution:
7 | def nextGreatestLetter(self, letters: List[str], target: str) -> str:
8 | lower, upper = 0, len(letters) - 1
9 |
10 | if target < letters[lower] or target >= letters[upper]: return letters[0]
11 |
12 | while lower < upper:
13 | mid = (upper + lower) // 2
14 |
15 | if letters[mid] > target:
16 | upper = mid
17 | else:
18 | lower = mid + 1
19 |
20 | return letters[upper];
21 |
22 | class Test(unittest.TestCase):
23 | def test_nextGreatestLetter(self):
24 | self.assertEqual(Solution.nextGreatestLetter(self, ['c', 'f', 'j'], 'a'), 'c')
25 | self.assertEqual(Solution.nextGreatestLetter(self, ['c', 'f', 'j'], 'c'), 'f')
26 | self.assertEqual(Solution.nextGreatestLetter(self, ['c', 'f', 'j'], 'd'), 'f')
27 | self.assertEqual(Solution.nextGreatestLetter(self, ['c', 'f', 'j'], 'j'), 'c')
28 |
29 |
30 | if __name__ == "__main__":
31 | unittest.main()
32 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/17-avgOfLevels.py:
--------------------------------------------------------------------------------
1 | # Definition for a binary tree node.
2 | # 0(n) - TC | 0(N) - SC
3 |
4 | from typing import Collection, List
5 | class TreeNode:
6 | def __init__(self, val=0, left=None, right=None):
7 | self.val = val
8 | self.left = left
9 | self.right = right
10 |
11 | class Solution:
12 | def averageOfLevels(self, root: TreeNode) -> List[float]:
13 | res = []
14 | queue = Collection.deque()
15 | queue.append(root)
16 |
17 | while queue:
18 | total = 0
19 | queueLen = len(queue)
20 |
21 | for _ in range(queueLen):
22 | node = queue.popleft()
23 | total += node.val
24 | if node.left: queue.append(node.left)
25 | if node.right: queue.append(node.right)
26 |
27 | res.append(total / queueLen)
28 |
29 | return res
30 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/18-minDepth.py:
--------------------------------------------------------------------------------
1 | # Definition for a binary tree node.
2 | class TreeNode:
3 | def __init__(self, val=0, left=None, right=None):
4 | self.val = val
5 | self.left = left
6 | self.right = right
7 |
8 | class Solution:
9 | def minDepth(self, root: TreeNode) -> int:
10 | if root is None: return 0
11 | leftDepth = self.minDepth(root.left)
12 | rightDepth = self.minDepth(root.right)
13 |
14 | if root.left is None and root.right is None: return 1
15 |
16 | if root.left is None: return rightDepth + 1
17 |
18 | if root.right is None: return leftDepth + 1
19 |
20 | return min(leftDepth, rightDepth) + 1
21 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/19-maxDepth.py:
--------------------------------------------------------------------------------
1 | # Definition for a binary tree node.
2 | class TreeNode:
3 | def __init__(self, val=0, left=None, right=None):
4 | self.val = val
5 | self.left = left
6 | self.right = right
7 | class Solution:
8 | def maxDepth(self, root: TreeNode) -> int:
9 | if root is None: return 0
10 |
11 | leftDepth = self.maxDepth(root.left)
12 |
13 | rightDepth = self.maxDepth(root.right)
14 |
15 | if root.left is None and root.right is None: return 1
16 |
17 | if root.left is None: return rightDepth + 1
18 |
19 | if root.right is None: return leftDepth + 1
20 |
21 | return max(leftDepth, rightDepth) + 1
22 |
23 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/20-isSameTree.py:
--------------------------------------------------------------------------------
1 | # Definition for a binary tree node.
2 | class TreeNode:
3 | def __init__(self, val=0, left=None, right=None):
4 | self.val = val
5 | self.left = left
6 | self.right = right
7 |
8 | # Bfs 0(N) - TC | SC
9 | # https://leetcode.com/problems/same-tree/
10 |
11 |
12 | class Solution:
13 | def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
14 | queue = [(p, q)]
15 |
16 | while queue:
17 | node1, node2 = queue.pop(0)
18 |
19 | if not node1 and not node2:
20 | continue
21 | elif not node1 or not node2:
22 | return False
23 | else:
24 | if node1.val != node2.val:
25 | return False
26 | queue.append((node1.left, node2.left))
27 | queue.append((node1.right, node2.right))
28 | return True
29 |
30 | # Dfs
31 | def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
32 | node1, node2 = p, q
33 |
34 | if not node1 and not node2:
35 | return True
36 | if not node1 or not node2:
37 | return False
38 |
39 | if node1.val != node2.val:
40 | return False
41 | return (self.isSameTree(node1.left, node2.left) and self.isSameTree(node1.right, node2.right))
42 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/21-pathSum.py:
--------------------------------------------------------------------------------
1 | # Definition for a binary tree node.
2 | class TreeNode:
3 | def __init__(self, val=0, left=None, right=None):
4 | self.val = val
5 | self.left = left
6 | self.right = right
7 | from typing import Optional
8 |
9 |
10 | class Solution:
11 | def hasPathSum(self, root: Optional[TreeNode], tsum: int) -> bool:
12 | if not root: return False
13 |
14 | if not root.left and not root.right:
15 | if tsum == root.val: return True
16 |
17 | return (self.hasPathSum(root.left, tsum - root.val) or
18 | self.hasPathSum(root.right, tsum - root.val))
19 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/22-twoSum.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | # https://leetcode.com/problems/two-sum/
5 | # 0(n) - time | 0(n) - space
6 | class Solution:
7 | def twoSum(self, nums: List[int], target: int) -> List[int]:
8 | hash = {}
9 |
10 | for i in range(len(nums)):
11 | diff = target - nums[i]
12 |
13 | if diff in hash:
14 | return [i, hash[diff]]
15 | hash[nums[i]] = i
16 |
17 | class Test(unittest.TestCase):
18 | def test_twoSum(self):
19 | self.assertEqual(Solution.twoSum(self, [2,7,11,15], 9), [1, 0])
20 | self.assertEqual(Solution.twoSum(self, [3,2,4], 6), [2, 1])
21 | self.assertEqual(Solution.twoSum(self, [3, 3], 6), [1, 0])
22 |
23 | if __name__ == "__main__":
24 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/23-invertBinaryTree.py:
--------------------------------------------------------------------------------
1 | # Definition for a binary tree node.
2 | from typing import Optional
3 |
4 |
5 | class TreeNode:
6 | def __init__(self, val=0, left=None, right=None):
7 | self.val = val
8 | self.left = left
9 | self.right = right
10 |
11 | # 0(n) - time | 0(n) - space
12 | # https://leetcode.com/problems/invert-binary-tree/
13 |
14 | class Solution:
15 | def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
16 | if not root: return root
17 |
18 | tmp = root.left
19 | root.left = root.right
20 | root.right = tmp
21 |
22 | self.invertTree(root.left)
23 | self.invertTree(root.right)
24 |
25 | return root
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/24-subTree.py:
--------------------------------------------------------------------------------
1 | # Definition for a binary tree node.
2 | class TreeNode:
3 | def __init__(self, val=0, left=None, right=None):
4 | self.val = val
5 | self.left = left
6 | self.right = right
7 | from typing import Optional
8 |
9 | # https://leetcode.com/problems/subtree-of-another-tree/
10 | # 0(r * s) - tc | 0(r * s) - sc
11 |
12 | class Solution:
13 | def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
14 | if subRoot and not root: return False
15 | if self.isMatch(root, subRoot): return True
16 |
17 | return (self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot))
18 |
19 |
20 | def isMatch(self, r, s):
21 | if r and s:
22 | return r.val == s.val and self.isMatch(r.left, s.left) and self.isMatch(r.right, s.right)
23 | return r is s
24 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/25-squareSortedArr.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest, collections
3 |
4 | # https://leetcode.com/problems/squares-of-a-sorted-array/
5 | # 0(n) - tc | 0(n) - sc
6 |
7 | class Solution:
8 | def sortedSquares(self, nums: List[int]) -> List[int]:
9 | res = collections.deque()
10 | l, r = 0, len(nums) - 1
11 |
12 | while l <= r:
13 |
14 | left, right = nums[l], nums[r]
15 |
16 | if abs(right) > abs(left):
17 | res.appendleft(right * right)
18 | r -= 1
19 | else:
20 | res.appendleft(left * left)
21 | l += 1
22 |
23 | return list(res)
24 |
25 |
26 | class Test(unittest.TestCase):
27 | def test_sortedSquare(self):
28 | self.assertEqual(Solution.sortedSquares(self, [-4,-1,0,3,10]), [0,1,9,16,100])
29 | self.assertEqual(Solution.sortedSquares(self, [-7,-3,2,3,11]), [4,9,9,49,121])
30 | self.assertEqual(Solution.sortedSquares(self, [-4,-1,3,10]), [1,9,16,100])
31 | self.assertEqual(Solution.sortedSquares(self, [1, 2, 3, 4]), [1,4,9,16])
32 |
33 | if __name__ == "__main__":
34 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/26-backspaceStringCompare.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | # https://leetcode.com/problems/backspace-string-compare/solutions/?orderBy=most_votes&languageTags=javascript&topicTags=two-pointers
4 | # 0(n) - TC | 0(1) - SC
5 |
6 | class Solution:
7 | def backspaceCompare(self, s: str, t: str) -> bool:
8 | sLen = len(s) - 1
9 | tLen = len(t) - 1
10 |
11 | sSkip, tSkip = 0, 0
12 | sNew, tNew = '', ''
13 |
14 | while(sLen >= 0 or tLen >= 0):
15 | while(sLen >= 0):
16 | if s[sLen] == '#':
17 | sSkip += 1
18 | elif sSkip > 0:
19 | sSkip -= 1
20 | else:
21 | sNew += s[sLen]
22 | sLen -= 1
23 |
24 | while tLen >= 0:
25 | if t[tLen] == '#':
26 | tSkip += 1
27 | elif tSkip > 0:
28 | tSkip -= 1
29 | else:
30 | tNew += t[tLen]
31 | tLen -= 1
32 |
33 | return tNew == sNew
34 |
35 | class Test(unittest.TestCase):
36 | def test_backspaceCompare(self):
37 | self.assertEqual(Solution.backspaceCompare(self, 'ab#cd#', 'ac#d#c'), True)
38 | self.assertEqual(Solution.backspaceCompare(self, "ab#c", 'ad#c'), True)
39 | self.assertEqual(Solution.backspaceCompare(self, "ab##", 'c#d#'), True)
40 | self.assertEqual(Solution.backspaceCompare(self, 'a#c', 'b'), False)
41 |
42 | if __name__ == "__main__":
43 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/27-majorityElement.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blossom-babs/Data-structures-and-algorithm/027b4e7a5037a5897789eafebbf828899313feff/leetcode/sean-prashad/python/27-majorityElement.py
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/3-findDisappearedNumbers.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/
6 | '''
7 |
8 | class Solution:
9 | # 0(n) - tc | 0(n) - sc
10 | def findDisappearedNumbers1(self, nums: List[int]) -> List[int]:
11 | numsSet, res = set(nums), []
12 |
13 | for i in range(1, len(nums) + 1):
14 | if i not in numsSet:
15 | res.append(i)
16 | return res
17 |
18 | # 0(n) - tc | 0(1) - sc
19 | def findDisappearedNumbers2(self, nums: List[int]) -> List[int]:
20 | i = 0
21 | res = []
22 |
23 | while i < len(nums):
24 | j = nums[i] - 1
25 |
26 | if nums[i] != nums[j]:
27 | nums[i], nums[j] = nums[j], nums[i]
28 | else:
29 | i += 1
30 |
31 | for i in range(len(nums) + 1):
32 | if i < len(nums) and i + 1 != nums[i]:
33 | res.append(i + 1)
34 | return res
35 |
36 | class Test(unittest.TestCase):
37 | def test_disappearedNum(self):
38 | self.assertEqual(Solution.findDisappearedNumbers1(self, [1, 1]), [2])
39 | self.assertEqual(Solution.findDisappearedNumbers1(self, [4,3,2,7,8,2,3,1]), [5, 6])
40 |
41 | def test_disappearedNum2(self):
42 | self.assertEqual(Solution.findDisappearedNumbers2(self, [1, 1]), [2])
43 | self.assertEqual(Solution.findDisappearedNumbers2(self, [4,3,2,7,8,2,3,1]), [5, 6])
44 |
45 |
46 | if __name__ == "__main__":
47 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/5-climbingStairs.py:
--------------------------------------------------------------------------------
1 | '''
2 | https://leetcode.com/problems/climbing-stairs/
3 | '''
4 | import unittest
5 |
6 |
7 | class Solution:
8 | #0(n) - tc | 0(n) - sc
9 | def climbStairs(self, n: int) -> int:
10 | count = [1, 2]
11 |
12 | for i in range(2, n):
13 | count.append((n - 1) + (n - 2))
14 | return count[n - 1]
15 |
16 | #0(2^n) - tc | 0(n) - sc
17 | def climbStairsRecurse(self, n: int) -> int:
18 | memo = {}
19 |
20 | def recurse(n):
21 | if n in memo:
22 | return memo[n]
23 | if n == 1:
24 | return 1
25 | if n == 2:
26 | return 2
27 | memo[n] = recurse(n - 1) + recurse(n - 2)
28 | return memo[n]
29 |
30 | return recurse(n)
31 |
32 |
33 | class Test(unittest.TestCase):
34 | def test_climbingStairs(self):
35 | self.assertEqual(Solution.climbStairs(self, 2), 2)
36 | self.assertEqual(Solution.climbStairs(self, 3), 3)
37 | self.assertEqual(Solution.climbStairs(self, 1), 1)
38 |
39 | def test_climbingStairsRecurse(self):
40 | self.assertEqual(Solution.climbStairsRecurse(self, 2), 2)
41 | self.assertEqual(Solution.climbStairsRecurse(self, 3), 3)
42 | self.assertEqual(Solution.climbStairsRecurse(self, 1), 1)
43 |
44 | if __name__ == "__main__":
45 | unittest.main()
46 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/6-bestTimeToSell.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
6 | 0(n) - tc | 0(1) - sc
7 | '''
8 |
9 | class Solution:
10 | def maxProfit(self, prices: List[int]) -> int:
11 | buy, sell = 0, 1
12 | profit = 0
13 |
14 | while sell < len(prices):
15 | sale = prices[sell] - prices[buy]
16 |
17 | if sale < 0:
18 | buy += 1
19 | else:
20 | profit = max(profit, sale)
21 | sell += 1
22 | return profit
23 |
24 |
25 | class Test(unittest.TestCase):
26 | def test_maxProfit(self):
27 | self.assertEqual(Solution.maxProfit(self, [7,1,5,3,6,4]), 5)
28 | self.assertEqual(Solution.maxProfit(self, [7,4,5,3,6,4]), 3)
29 | self.assertEqual(Solution.maxProfit(self, [7,6,4,3,1]), 0)
30 |
31 | if __name__ == "__main__":
32 | unittest.main()
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/7-rangeSumQuery.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | import unittest
3 |
4 | '''
5 | https://leetcode.com/problems/range-sum-query-immutable/
6 | 0(n) - tc | 0(n) - sc
7 | '''
8 |
9 | # prefix sum
10 | class NumArray:
11 |
12 | def __init__(self, nums: List[int]):
13 | self.nums = [0]
14 | for num in nums:
15 | self.nums.append(self.nums[-1] + num)
16 |
17 |
18 | def sumRange(self, left: int, right: int) -> int:
19 | return self.nums[right + 1] - self.nums[left]
20 |
21 | # Brute force
22 | class NumArray:
23 |
24 | def __init__(self, nums: List[int]):
25 | self.nums = nums
26 |
27 |
28 | def sumRange(self, left: int, right: int) -> int:
29 | return sum(self.nums[left: right + 1])
30 |
31 |
32 |
33 | class Test(unittest.TestCase):
34 | def test_NumArray(self):
35 | NumArray.__init__(self, [-2, 0, 3, -5, 2, -1])
36 | param = NumArray.sumRange(self, 0, 2)
37 | param2 = NumArray.sumRange(self, 2, 5)
38 | param3 = NumArray.sumRange(self, 0, 5)
39 | self.assertEqual(param, 1)
40 | self.assertEqual(param2, -1)
41 | self.assertEqual(param3, -3)
42 |
43 |
44 | if __name__ == "__main__":
45 | unittest.main()
46 |
47 | # Your NumArray object will be instantiated and called as such:
48 | # obj = NumArray(nums)
49 | # param_1 = obj.sumRange(left,right)
50 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/8-hasCycle.py:
--------------------------------------------------------------------------------
1 | # Definition for singly-linked list.
2 | class ListNode:
3 | def __init__(self, x):
4 | self.val = x
5 | self.next = None
6 |
7 | from typing import Optional
8 |
9 | '''
10 | https://leetcode.com/problems/linked-list-cycle/
11 | '''
12 |
13 | # Set patter
14 | # 0(n) - tc | 0(n) - sc
15 | class Solution:
16 | def hasCycle(self, head: Optional[ListNode]) -> bool:
17 | cycle = set()
18 | while head:
19 | if head in cycle:
20 | return True
21 | cycle.add(head)
22 | head = head.next
23 | return False
24 |
25 |
26 | # Floyd's cycle detection algorithm
27 | # 0(n) - TC | 0(1) - SC
28 | class Solution:
29 | def hasCycle(self, head: Optional[ListNode]) -> bool:
30 | slow = fast = head
31 |
32 | while fast and fast.next:
33 | slow = slow.next
34 | fast = fast.next.next
35 |
36 | if slow == fast:
37 | return True
38 | return False
39 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/9-middleLinkedList.py:
--------------------------------------------------------------------------------
1 | # Definition for singly-linked list.
2 | class ListNode:
3 | def __init__(self, val=0, next=None):
4 | self.val = val
5 | self.next = next
6 | from typing import Optional
7 |
8 | '''
9 | https://leetcode.com/problems/middle-of-the-linked-list/
10 | '''
11 |
12 | # 0(n) - tc | 0(1) - sc
13 | class Solution:
14 | def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
15 | slow = fast = head
16 | while fast and fast.next:
17 | fast = fast.next.next
18 | slow = slow.next
19 | return slow
20 |
21 |
22 | # Brute force approach
23 | # 0(n ^ 2) - TC | 0(1) - sc
24 | class Solution:
25 | def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
26 | listLen = 0
27 | temp = head
28 |
29 | while temp:
30 | listLen += 1
31 | temp = temp.next
32 |
33 | mid = listLen // 2
34 | pos = 0
35 |
36 |
37 | while head:
38 | if pos == mid:
39 | return head
40 | head = head.next
41 | pos += 1
42 |
--------------------------------------------------------------------------------
/leetcode/sean-prashad/python/bonus-linkedlistII.py:
--------------------------------------------------------------------------------
1 | # Definition for singly-linked list.
2 | from typing import Optional
3 |
4 |
5 | class ListNode:
6 | def __init__(self, x):
7 | self.val = x
8 | self.next = None
9 |
10 |
11 | '''
12 | https://leetcode.com/problems/linked-list-cycle-ii/submissions/
13 | '''
14 |
15 | # set solution
16 | # 0(n) - tc | 0(n) - sc
17 |
18 |
19 | class Solution:
20 | def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
21 | hash = set()
22 | current = head
23 |
24 | while current:
25 | if current in hash:
26 | return current
27 | hash.add(current)
28 | current = current.next
29 |
30 | return None
31 |
32 |
33 | class Solution:
34 | def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
35 | slow = fast = pointer = head
36 |
37 | while fast and fast.next:
38 | slow = slow.next
39 | fast = fast.next.next
40 |
41 | if fast == slow:
42 | slow = head
43 | while slow != fast:
44 | slow = slow.next
45 | fast = fast.next
46 | return slow
47 |
48 | return None
49 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "data-structure-and-algorithms",
3 | "version": "1.0.0",
4 | "description": "This repository holds solutions to my solutions to data structures and algorithmic problems.",
5 | "main": "",
6 | "scripts": {
7 | "test": "jest --coverage",
8 | "start": "clear && npm test ./leetcode/sean-prashad/javascript/28-productExceptSelf.test.js",
9 | "start-js-tree": "clear && node ./data-structures/binary-trees/javascript/createNodeClass.test.js",
10 | "run-py": "clear && python ./data-structures/binary-trees/python/1-createNodeClass.py"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/blossom-babs/leetcode-challenges.git"
15 | },
16 | "keywords": [],
17 | "author": "",
18 | "license": "ISC",
19 | "bugs": {
20 | "url": "https://github.com/blossom-babs/leetcode-challenges/issues"
21 | },
22 | "homepage": "https://github.com/blossom-babs/leetcode-challenges#readme",
23 | "devDependencies": {
24 | "@types/jest": "^27.4.1",
25 | "jest": "^27.5.1"
26 | },
27 | "dependencies": {
28 | "js-ord": "^4.1.1"
29 | }
30 | }
--------------------------------------------------------------------------------