├── .github ├── CONTRIBUTING.md ├── TEMPLATES │ └── SOLUTION-README.md └── workflows │ └── main.yml ├── README.md ├── edabit ├── add-single-number-ts │ ├── README.md │ └── index.ts └── match-houses-ts │ ├── README.md │ ├── image.png │ └── index.ts ├── hackerrank ├── Insert-to-head-js │ ├── README.md │ └── index.js ├── LinkedList-addto-tail-js │ ├── README.md │ └── index.js ├── fizzBuzz-ts │ ├── README.md │ └── index.ts ├── print-elements-of-linkedlist-js │ ├── README.md │ └── index.js └── reverse-array-ts │ ├── README.md │ └── index.ts └── leetcode ├── 3sum-ts ├── README.md └── index.ts ├── How Many Numbers Are Smaller Than the Current Number-js ├── README.md └── index.js ├── Maximum-average-subarray-js ├── README.md └── index.js ├── Palindrome-LinkedList-ts ├── README.md └── index.ts ├── README.md ├── Sorting the Sentence-js ├── README.md └── index.js ├── Unique Number of Occurrences - js ├── README.md └── index.js ├── absolute-k-diff-ts ├── README.md └── index.ts ├── add-two-numbers-ts ├── README.md └── index.ts ├── house-robber-ts ├── README.md └── index.ts ├── maximu-69-number-ts ├── README.md └── index.ts ├── median-sorted-arr-ts ├── README.md └── index.ts ├── move-zeroes-js ├── README.md └── index.js ├── orderly-queue-ts ├── README.md └── index.ts ├── palindrome-number-js ├── README.md └── index.js ├── plus-one-js ├── README.md └── index.js ├── reverse-integer-ts ├── README.md └── index.ts ├── reverse-vowels-ts ├── README.md └── index.ts ├── roman-to-int-ts ├── README.md └── index.ts ├── substring-without-rep-ts ├── README.md └── index.ts ├── two-sum-ts ├── README.md └── index.ts └── valid-palindrome-ts ├── README.md └── index.ts /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## HOW TO CONTRIBUTE TO THIS REPOSITORY 2 | 3 | This repository is created with the **sole** purpose of challenging contributors to solve DSA problems in Typescript. 4 | Anything aside from this intention highly **discouraged**. 5 | 6 | ### :dart: Getting Started 7 | Feel free to contribute to this repository by adding your own solutions to the problems. Let's learn together.👯‍♂️ 8 | 9 | ### :sparkles: Problem Sources 10 | The problems are sourced from various platforms like Leetcode, HackerRank. 11 | Make sure your problem is sourced from one of these platforms. 12 | - [Leetcode](https://leetcode.com/); 13 | - [HackerRank](https://www.hackerrank.com/); 14 | - [Edabit](https://www.edabit.com/); 15 | 16 | If your problem source is not listed here, please create an issue and we will add it to the list. 17 | 18 | ### :rocket: Languages Used 19 | - [TypeScript](https://www.typescriptlang.org/) 20 | - [JavaScript](https://www.javascript.com/) 21 | - [Python](https://www.python.org/) 22 | 23 | If your preferred language is not listed here, please create an issue and we will add it to the list. 24 | 25 | **Your code must be written in one of the languages listed above.** 26 | 27 | ### :white_check_mark: Contribution Guidelines 28 | - Create a folder with the name of the problem in the respective source folder. `i.e. leetcode/two-sum-ts or hackerrank/counting-valleys-js` 29 | - The folder name should be in `kebab-case`. 30 | - It must end with the language extension. `i.e. -ts or -js` 31 | - Include a README.md file in your solution folder. This file should contain: 32 | - the problem statement and the link to the problem source. 33 | - The time and space complexity of your solution. 34 | - Your solution should be written in a file named `index.ts` or `index.js` in your solution folder. 35 | - Make sure your code is well documented. 36 | - Make sure your code is well formatted and linted for readability. 37 | - Your code must have at least three(3) test cases. 38 | - Make sure your code passes all the test cases on the problem source before submitting a PR. 39 | 40 | 41 | ### :checkered_flag: PR Requirements 42 | - Your PR title should be in the format `[SourceName] ProblemName TS/JS`. 43 | - It should be `JS` or `TS` depending on the language you used. 44 | - Your PR will be rejected if it does not follow this format. 45 | - The PR must have a description. 46 | - The description can be the same as the content of your README.md file. 47 | - Your PR should only contain the solution to the problem you are solving. 48 | - Add the `NEW` label to your PR. 49 | - Add the language you used to solve the problem as a label to your PR. `i.e. JavaScript or TypeScript` 50 | - Add the `READY FOR REVIEW` label to your PR. 51 | - Your code will not be reviewed if you do not add this label. 52 | - A maintainer will review your PR and merge it if it meets the requirements. 53 | 54 | ## :checkered_flag: Contribute to an Existing solution 55 | - First Create an issue on why you want to contribute to the existing solution. 56 | - Make sure your solution has a better time and space complexity than the existing solution. 57 | - Your code must pass all the test cases on the problem source. 58 | - Your PR must be linked to the issue you created. This will help us keep track of the issue. 59 | - Your PR title should be in the format `UPDATE: [SourceName] ProblemName TS/JS`. 60 | - Your PR will be rejected if it does not follow this format. 61 | - Add the `UPDATE` label to your PR. 62 | - Add the language you used to solve the problem as a label to your PR. `i.e. JavaScript or TypeScript` 63 | - Add the `READY FOR REVIEW` label to your PR. 64 | - Your code will not be reviewed if you do not add this label. 65 | - A maintainer will review your PR and merge it if it meets the requirements. 66 | 67 | ### :star: How to get your PR merged 68 | - Your PR must follow all the PR requirements above. -------------------------------------------------------------------------------- /.github/TEMPLATES/SOLUTION-README.md: -------------------------------------------------------------------------------- 1 | ## [SOURCE NAME] - [PROBLEM NAME] 2 | *Problem description here.* 3 | 4 | **Problem Source:** [SOURCE NAME](SOURCE LINK) 5 | 6 | 7 | ## TEST CASES 8 | ```javascript 9 | // Describe test cases here 10 | ``` 11 | 12 | ## Time Complexity 13 | ..... 14 | 15 | ## Space Complexity 16 | ..... 17 | 18 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | 6 | jobs: 7 | contrib-readme-job: 8 | runs-on: ubuntu-latest 9 | name: A job to automate contrib in readme 10 | steps: 11 | - name: Contribute List 12 | uses: akhilmhdh/contributors-readme-action@v2.3.6 13 | env: 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

DSA PROBLEM SOLUTIONS

2 | 3 |

4 | Github top language 5 | 6 | Github language count 7 | 8 | Repository size 9 | 10 | License 11 | 12 | Github issues 13 | 14 | Github forks 15 | 16 | Github stars 17 |

18 | 19 | 20 | 21 |

22 | 🚧 DSA PROBLEM SOLUTIONS 🚀 On going daily... 🚧 23 |

24 | 25 |
26 | 27 |

28 | About   |   29 | Features   |   30 | Technologies   |   31 | Requirements   |   32 | Starting   |   33 | Contributors 34 |

35 | 36 |
37 | 38 | ## :dart: About 39 | 40 | This repository contains the solution of various DSA problems from various platforms like Leetcode, HackerRank, CodeChef, CodeForces, etc. in Typescript. 41 | 42 | Feel free to contribute to this repository by adding your own solutions to the problems. 43 | Let's learn together.👯‍♂️ 44 | 45 | ## :sparkles: Problem Sources 46 | 47 | :heavy_check_mark: [Leetcode](https://leetcode.com/);\ 48 | :heavy_check_mark: [HackerRank](https://www.hackerrank.com/);\ 49 | :heavy_check_mark: [CodeChef](https://www.codechef.com/);\ 50 | :heavy_check_mark: [Edabit](https://edabit.com/challenges); 51 | 52 | ## :rocket: Technologies 53 | 54 | The following tools were used in this project: 55 | 56 | - [TypeScript](https://www.typescriptlang.org/) 57 | - [JavaScript](https://www.javascript.com/) 58 | - [Python](https://www.python.org/) 59 | 60 | ## :white_check_mark: Requirements 61 | 62 | Before starting :checkered_flag:, you need to have [ts-node](https://www.typescriptlang.org/), [Git](https://git-scm.com) and [Node](https://nodejs.org/en/) installed. 63 | 64 | ## :checkered_flag: Starting 65 | 66 | ```bash 67 | # Clone this project 68 | $ git clone https://github.com/qbentil/dsa-typescript 69 | 70 | # Access 71 | $ cd dsa-typescript 72 | 73 | ``` 74 | 75 | 76 | ## :memo: Contributors 77 | 78 | These wonderful people have contributed to this project: 79 | 80 | 81 | 82 | 83 | 90 | 97 | 104 | 111 |
84 | 85 | qbentil 86 |
87 | Bentil Shadrack 88 |
89 |
91 | 92 | neophyte-programmer 93 |
94 | Nutifafa Afi Attor 95 |
96 |
98 | 99 | samtuga1 100 |
101 | Samuel Twumasi 102 |
103 |
105 | 106 | KingsleyAmankwah 107 |
108 | Kingsley✨ 109 |
110 |
112 | 113 | 114 | ## Project Maintainers 115 | 116 | 117 | 118 | 125 | 132 |
119 | 120 | qbentil 121 |
122 | Bentil Shadrack 123 |
124 |
126 | 127 | neophyte-programmer 128 |
129 | Nutifafa Afi Attor 130 |
131 |
133 | 134 | 135 | This project follows the [all-contributors](#) specification. Contributions of any kind are welcome! \ 136 | You are welcome to contribute to this project. 137 | 138 | Please read the [CONTIBUTING.md](https://github.com/neophyte-programmer/dsa-typescript/blob/master/.github/CONTRIBUTING.md) file for details on our code of conduct, and the process for submitting pull requests to us. 139 | 140 | 141 |   142 | 143 | Back to top 144 | -------------------------------------------------------------------------------- /edabit/add-single-number-ts/README.md: -------------------------------------------------------------------------------- 1 | ## Edabit - Add up the Numbers from a Single Number 2 | Create a function that takes a number as an argument. Add up all the numbers from 1 to the number you passed to the function. For example, if the input is 4 then your function should return 10 because 1 + 2 + 3 + 4 = 10. 3 | 4 | **Problem Source:** [Edabit](https://edabit.com/challenge/4gzDuDkompAqujpRi) 5 | 6 | ## TEST CASES 7 | ```javascript 8 | // TEST CASE 1 9 | console.log(addUp(4)) // 10 10 | 11 | // TEST CASE 2 12 | console.log(addUp(13)) // 91 13 | 14 | // TEST CASE 3 15 | console.log(addUp(600)) // 180300 16 | 17 | ``` 18 | -------------------------------------------------------------------------------- /edabit/add-single-number-ts/index.ts: -------------------------------------------------------------------------------- 1 | function addUp(num: number): number { 2 | let result = 0 3 | for (let i = 1; i <= num; i++){ 4 | result += i 5 | } 6 | return result 7 | } -------------------------------------------------------------------------------- /edabit/match-houses-ts/README.md: -------------------------------------------------------------------------------- 1 | ## Edabit - Matchstick Houses 2 | This challenge will help you interpret mathematical relationships both algebraically and geometrically. 3 | 4 | ![](image.png) 5 | 6 | Create a function that takes a number (step) as an argument and returns the number of matchsticks in that step. See step 1, 2 and 3 in the image above. 7 | 8 | **Problem Source:** [Edabit](https://edabit.com/challenge/tYHkTdFrEmWfxpPKF) 9 | 10 | ## TEST CASES 11 | ```javascript 12 | // TEST CASE 1 13 | console.log(matchHouses(1)) // 6 14 | 15 | // TEST CASE 2 16 | console.log(matchHouses(4)) // 21 17 | 18 | // TEST CASE 3 19 | console.log(matchHouses(87)) // 436 20 | 21 | ``` 22 | ## NOTES 23 | - Step 0 returns 0 matchsticks. 24 | - The input (step) will always be a non-negative integer. 25 | - Think of the input (step) as the total number of houses that have been connected together. -------------------------------------------------------------------------------- /edabit/match-houses-ts/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neophyte-programmer/dsa-solutions/ea64314b0dbb8606b6249fd9abd3cc30f0a659da/edabit/match-houses-ts/image.png -------------------------------------------------------------------------------- /edabit/match-houses-ts/index.ts: -------------------------------------------------------------------------------- 1 | function matchHouses(step: number): number { 2 | return step <= 0 ? 0 : (6 * step) - (step - 1) 3 | } -------------------------------------------------------------------------------- /hackerrank/Insert-to-head-js/README.md: -------------------------------------------------------------------------------- 1 | ## HackerRank - LinkedList-addto-Head-JS 2 | 3 | ### Problem 4 | Given a pointer to the head of a linked list, insert a new node before the head. The next value in the new node should point to the head and the data value should be replaced with a given value. Return a reference to the new head of the list. The head pointer given may be null meaning that the initial list is empty. 5 | 6 | ### Problem Source 7 | [https://www.hackerrank.com/challenges/insert-a-node-at-the-head-of-a-linked-list/problem](https://www.hackerrank.com/challenges/insert-a-node-at-the-head-of-a-linked-list/problem) 8 | 9 | ### Solution 10 | ```javascript 11 | 12 | function function insertNodeATHead(head, data) { 13 | let newNode = {data, next: null}; 14 | if (head){ 15 | newNode.next = head; 16 | } 17 | head = newNode; 18 | 19 | if(!head.tail){ 20 | head.tail = newNode; 21 | } 22 | return head; 23 | } 24 | 25 | ``` 26 | 27 | ### Analysis 28 | 29 | #### Time Complexity 30 | **O(1)** 31 | 32 | #### Space Complexity 33 | **O(1)** 34 | 35 | #### Runtime 36 | **0.5s** -------------------------------------------------------------------------------- /hackerrank/Insert-to-head-js/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {*} head 4 | * @param {*} data 5 | * @returns 6 | */ 7 | function insertNodeATHead(head, data) { 8 | let newNode = {data, next: null}; 9 | if (head){ 10 | newNode.next = head; 11 | } 12 | head = newNode; 13 | 14 | if(!head.tail){ 15 | head.tail = newNode; 16 | } 17 | return head; 18 | } -------------------------------------------------------------------------------- /hackerrank/LinkedList-addto-tail-js/README.md: -------------------------------------------------------------------------------- 1 | ## HackerRank - LinkedList-addto-tail-js 2 | 3 | ### Problem 4 | You are given the pointer to the head node of a linked list and an integer to add to the list. Create a new node with the given integer. Insert this node at the tail of the linked list and return the head node of the linked list formed after inserting this new node. The given head pointer may be null, meaning that the initial list is empty. 5 | 6 | ### Problem Source 7 | [https://www.hackerrank.com/challenges/insert-a-node-at-the-tail-of-a-linked-list/problem](https://www.hackerrank.com/challenges/insert-a-node-at-the-tail-of-a-linked-list/problem) 8 | 9 | ### Solution 10 | ```javascript 11 | 12 | function insertNodeAtTail(head, data) { 13 | let node = { 14 | data: data, 15 | next: null 16 | }; 17 | if (!head) { 18 | head = node; 19 | } 20 | if(head.tail) { 21 | head.tail.next = node; 22 | } 23 | head.tail = node; 24 | return head; 25 | } 26 | 27 | ``` 28 | 29 | ### Analysis 30 | 31 | #### Time Complexity 32 | **O(1)** 33 | 34 | #### Space Complexity 35 | **O(1)** 36 | 37 | #### Runtime 38 | **0.5s** -------------------------------------------------------------------------------- /hackerrank/LinkedList-addto-tail-js/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | 5 | function insertNodeAtTail(head, data){ 6 | const newNode = {data, next: null}; 7 | if (!head) { 8 | head = newNode; 9 | } 10 | if (head.tail) { 11 | head.tail.next = newNode; 12 | } 13 | head.tail = newNode; 14 | return head; 15 | } 16 | -------------------------------------------------------------------------------- /hackerrank/fizzBuzz-ts/README.md: -------------------------------------------------------------------------------- 1 | ## HackerRank - FizzBuzz 2 | Write a short program that prints each number from 1 to 100 on a new line. 3 | 4 | For each multiple of 3, print "Fizz" instead of the number. 5 | 6 | For each multiple of 5, print "Buzz" instead of the number. 7 | 8 | For numbers which are multiples of both 3 and 5, print "FizzBuzz" instead of the number. 9 | 10 | **Problem Source:** [HackerRank](https://www.hackerrank.com/challenges/fizzbuzz/problem) 11 | 12 | 13 | ## TEST CASES 14 | ```javascript 15 | fizzBuzz(15) // 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz 16 | 17 | // TEST CASE 2 18 | fizzBuzz(5) // 1, 2, Fizz, 4, Buzz 19 | 20 | // TEST CASE 3 21 | fizzBuzz(3) // 1, 2, Fizz 22 | ``` 23 | ## Time Complexity 24 | **O(n)** 25 | 26 | ## Space Complexity 27 | **O(1)** -------------------------------------------------------------------------------- /hackerrank/fizzBuzz-ts/index.ts: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * @param n : number 5 | * @returns void 6 | */ 7 | 8 | function fizzBuzz(n: number): void { 9 | let i:number = 1; 10 | for(i = 1; i <=n; i++ ) 11 | { 12 | if(i % 15 == 0){ 13 | console.log("FizzBuzz"); 14 | }else if(i % 3 == 0){ 15 | console.log("Fizz") 16 | }else if(i % 5 == 0){ 17 | console.log("Buzz") 18 | }else{ 19 | console.log(i) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /hackerrank/print-elements-of-linkedlist-js/README.md: -------------------------------------------------------------------------------- 1 | ## HackerRank - Print Elements of a Linked List - JavaScript 2 | 3 | ### Problem Statement 4 | This is to practice traversing a linked list. Given a pointer to the head node of a linked list, print each node's data element, one per line. If the head pointer is null (indicating the list is empty), there is nothing to print. 5 | 6 | ### Function Description 7 | Complete the function printLinkedList in the editor. It should print each element of the linked list on a new line. 8 | printLinkedList has the following parameter(s): 9 | * SingleLinkedListNode head: a reference to the head of the list 10 | 11 | #### print 12 | * For each node, print its data element on a new line. 13 | 14 | ### Input Format 15 | The first line of input contains , the number of elements in the linked list. 16 | The next lines contain one element each, which are the elements of the linked list. 17 | **Note:** Do not read any input from stdin/console. Complete the printLinkedList function in the editor. 18 | 19 | ### Sample Input 20 | ``` 21 | 2 22 | 16 23 | 13 24 | ``` 25 | 26 | ### Sample Output 27 | ``` 28 | 16 29 | 13 30 | ``` 31 | 32 | ### Explanation 33 | There are two elements in the linked list. They are represented as 16 -> 13 -> NULL. So, the output is 16 -> 13 -> NULL. 34 | 35 | 36 | ### Solution 37 | ```javascript 38 | function printLinkedList(head) { 39 | let current = head; 40 | while (current) { 41 | console.log(current.data); 42 | current = current.next; 43 | } 44 | } 45 | ``` 46 | 47 | ### Time Complexity 48 | **O(n)** 49 | 50 | ### Space Complexity 51 | **O(1)** 52 | 53 | ### Test Cases 54 | ```javascript 55 | // TEST CASE 1 56 | const head1 = new SinglyLinkedListNode(16); 57 | head1.next = new SinglyLinkedListNode(13); 58 | printLinkedList(head1); // 16 13 59 | 60 | // TEST CASE 2 61 | const head2 = new SinglyLinkedListNode(16); 62 | head2.next = new SinglyLinkedListNode(13); 63 | head2.next.next = new SinglyLinkedListNode(7); 64 | printLinkedList(head2); // 16 13 7 65 | 66 | ``` 67 | -------------------------------------------------------------------------------- /hackerrank/print-elements-of-linkedlist-js/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {head} head 3 | * @param {number} data 4 | */ 5 | 6 | function printLinkedList(head) { 7 | let current = head; 8 | while (current) { 9 | console.log(current.data); 10 | current = current.next; 11 | } 12 | } -------------------------------------------------------------------------------- /hackerrank/reverse-array-ts/README.md: -------------------------------------------------------------------------------- 1 | ## HackerRank - Data Structures > Arrays > Arrays - DS 2 | An array is a type of data structure that stores elements of the same type in a contiguous block of memory. In an array, A, of size N, each memory location has some unique index, i (where 0 <= i < N), that can be referenced as A[i] (you may also see it written as Ai). 3 | 4 | Reverse an array of integers. 5 | 6 | **Example** 7 | A = [1,2,3] 8 | Return [3,2,1]. 9 | 10 | **Function Description** 11 | Complete the function reverseArray in the editor below. 12 | 13 | reverseArray has the following parameter(s): 14 | 15 | int A[n]: the array to reverse 16 | 17 | **Returns** 18 | 19 | int[n]: the reversed array 20 | 21 | **Input Format** 22 | 23 | The first line contains an integer, n, the number of integers in A. 24 | The second line contains n space-separated integers that make up A. 25 | 26 | **Constraints** 27 | 1 <= n <= 10^3 28 | 1 <= A[i] <= 10^4, where A[i] is the ith integer in A. 29 | 30 | **Sample Input 1** 31 | ``` 32 | 4 33 | 1 4 3 2 34 | ``` 35 | **Sample Output 1** 36 | ``` 37 | 2 3 4 1 38 | ``` 39 | 40 | **Explanation 1** 41 | When we reverse the array A=[1,4,3,2], we get A=[2,3,4,1]. 42 | 43 | **Sample Input 2** 44 | ``` 45 | 2 46 | 1 2 47 | ``` 48 | **Sample Output 2** 49 | ``` 50 | 2 1 51 | ``` 52 | 53 | **Explanation 2** 54 | When we reverse the array A=[1,2], we get A=[2,1]. 55 | 56 | **Problem Source:** [HackerRank](https://www.hackerrank.com/challenges/arrays-ds/problem) 57 | 58 | ## TEST CASES 59 | ```javascript 60 | reverseArray([1, 2, 3, 4, 5]) // [5, 4, 3, 2, 1] 61 | reverseArray([1, 2, 3, 4]) // [4, 3, 2, 1] 62 | reverseArray([1, 2, 3]) // [3, 2, 1] 63 | reverseArray([1, 2]) // [2, 1] 64 | reverseArray([1]) // [1] 65 | ``` 66 | ## Time Complexity 67 | **O(n)** 68 | ## Space Complexity 69 | **O(n)** 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /hackerrank/reverse-array-ts/index.ts: -------------------------------------------------------------------------------- 1 | function reverseArray(a: number[]): number[] { 2 | return a.reverse(); 3 | const reversedArray:number[] = []; 4 | for (let i = a.length - 1; i >= 0; i--) { 5 | reversedArray.push(a[i]); 6 | } 7 | return reversedArray; 8 | 9 | } -------------------------------------------------------------------------------- /leetcode/3sum-ts/README.md: -------------------------------------------------------------------------------- 1 | ## LEETCODE - 3SUM 2 | 3 | ### Problem 4 | Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0. 5 | Notice that the solution set must not contain duplicate triplets. 6 | 7 | **Problem Source:** [leetcode.com](https://leetcode.com/problems/3sum/) 8 | 9 | ### Example 1: 10 | ``` 11 | Input: nums = [-1,0,1,2,-1,-4] 12 | Output: [[-1,-1,2],[-1,0,1]] 13 | ``` 14 | 15 | ### Solution 16 | ```typescript 17 | function threeSum(nums: number[]): number[][] { 18 | const result: number[][] = []; 19 | nums.sort((a, b) => a - b); 20 | for (let i = 0; i < nums.length - 2; i++) { 21 | if (i > 0 && nums[i] === nums[i - 1]) { 22 | continue; 23 | } 24 | let left = i + 1; 25 | let right = nums.length - 1; 26 | while (left < right) { 27 | const sum = nums[i] + nums[left] + nums[right]; 28 | if (sum === 0) { 29 | result.push([nums[i], nums[left], nums[right]]); 30 | while (left < right && nums[left] === nums[left + 1]) { 31 | left++; 32 | } 33 | while (left < right && nums[right] === nums[right - 1]) { 34 | right--; 35 | } 36 | left++; 37 | right--; 38 | } else if (sum < 0) { 39 | left++; 40 | } else { 41 | right--; 42 | } 43 | } 44 | } 45 | return result; 46 | }; 47 | ``` 48 | 49 | ### CODE ANALYSIS 50 | 51 | #### Time Complexity 52 | O(n^2) 53 | 54 | #### Space Complexity 55 | O(1) 56 | 57 | -------------------------------------------------------------------------------- /leetcode/3sum-ts/index.ts: -------------------------------------------------------------------------------- 1 | function threesum(nums: number[]) : number[][] { 2 | const result: number[][] = []; 3 | nums.sort((a, b) => a - b); 4 | for (let i = 0; i < nums.length - 2; i++) { 5 | if (i > 0 && nums[i] === nums[i - 1]) { 6 | continue; 7 | } 8 | let j = i + 1; 9 | let k = nums.length - 1; 10 | while (j < k) { 11 | const sum = nums[i] + nums[j] + nums[k]; 12 | if (sum === 0) { 13 | result.push([nums[i], nums[j], nums[k]]); 14 | j++; 15 | while (j < k && nums[j] === nums[j - 1]) { 16 | j++; 17 | } 18 | } else if (sum < 0) { 19 | j++; 20 | } else { 21 | k--; 22 | } 23 | } 24 | } 25 | return result; 26 | } 27 | -------------------------------------------------------------------------------- /leetcode/How Many Numbers Are Smaller Than the Current Number-js/README.md: -------------------------------------------------------------------------------- 1 | ## LeetCode - How Many Numbers Are Smaller Than the Current Number 2 | Given the array nums, for each nums[i] find out how many numbers in the array are smaller than it. That is, for each nums[i] you have to count the number of valid j's such that j != i and nums[j] < nums[i]. 3 | 4 | Return the answer in an array. 5 | 6 | **Problem Source:** [LeetCode](https://leetcode.com/problems/how-many-numbers-are-smaller-than-the-current-number/) 7 | 8 | 9 | ## TEST CASES 10 | ```javascript 11 | // TEST CASE 1 12 | smallerNumbersThanCurrent([8,1,2,2,3]) // [4,0,1,1,3] 13 | 14 | // TEST CASE 2 15 | smallerNumbersThanCurrent([6,5,4,8]) // [2,1,0,3] 16 | 17 | // TEST CASE 3 18 | smallerNumbersThanCurrent([7,7,7,7]) // [0,0,0,0] 19 | ``` 20 | ## Time Complexity 21 | **O(n^2)** 22 | 23 | ## Space Complexity 24 | **O(1)** 25 | -------------------------------------------------------------------------------- /leetcode/How Many Numbers Are Smaller Than the Current Number-js/index.js: -------------------------------------------------------------------------------- 1 | var smallerNumbersThanCurrent = function(nums) { 2 | let count = Array(nums.length).fill(0) 3 | nums.map(num => { 4 | for(let i = 0; i < nums.length; i++) { 5 | if(nums[i] > num) { 6 | count[i]++; 7 | } 8 | } 9 | }) 10 | return count; 11 | }; 12 | -------------------------------------------------------------------------------- /leetcode/Maximum-average-subarray-js/README.md: -------------------------------------------------------------------------------- 1 | ## LEETCODE 643. Maximum Average Subarray I - JavaScript 2 | 3 | ### Problem 4 | 5 | You are given an integer array arr consisting of n elements, and an integer k. 6 | 7 | Find a contiguous subarray whose length is equal to k that has the maximum average value and return this value. Any answer with a calculation error less than 10-5 will be accepted. 8 | 9 | ### Example 1 10 | 11 | ``` 12 | Input: arr = [1,12,-5,-6,50,3], k = 4 13 | Output: 12.75000 14 | Explanation: Maximum average is (12 - 5 - 6 + 50) / 4 = 51 / 4 = 12.75 15 | ``` 16 | 17 | ### Example 2 18 | 19 | ``` 20 | Input: arr = [5], k = 1 21 | Output: 5.00000 22 | ``` 23 | 24 | ### Constraints 25 | 26 | ``` 27 | n == nums.length 28 | 1 <= k <= n <= 105 29 | -104 <= arr[i] <= 104 30 | ``` 31 | 32 | ## Problem Source 33 | 34 | [LeetCode 643. Maximum Average Subarray I](https://leetcode.com/problems/maximum-average-subarray-i/) 35 | 36 | ## Solution 37 | 38 | ``` 39 | function findAveragesOfSubarrays(arr, k) { 40 | //sliding window approach 41 | 42 | const results = [] 43 | let windowSum = 0 44 | let windowStart = 0 45 | 46 | for(let windowEnd = 0; windowEnd < arr.length; windowEnd++) { 47 | //add the next element 48 | windowSum += arr[windowEnd] 49 | 50 | //slide the window forward 51 | //we don't need to slide if we have not hit the required window size of k 52 | 53 | if (windowEnd >= k - 1) { 54 | //we are **AUTOMATICALLY** returning the window average once we hit the window size of k 55 | //and pushing to the output array 56 | results.push(windowSum/k) 57 | 58 | //subtracting the element going out 59 | windowSum -= arr[windowStart] 60 | 61 | //then sliding the window forward 62 | windowStart++ 63 | 64 | //adding the element coming in, in the outer/previous loop 65 | //and repeating this process until we hit the end of the array 66 | } 67 | } 68 | return results 69 | } 70 | 71 | findAveragesOfSubarrays([1, 3, 2, 6, -1, 4, 1, 8, 2], 5)//[2.2, 2.8, 2.4, 3.6, 2.8] 72 | ``` 73 | -------------------------------------------------------------------------------- /leetcode/Maximum-average-subarray-js/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} arr 3 | * @param {number} k 4 | * @return {number} 5 | */ 6 | 7 | function findAveragesOfSubarrays(arr, k) { 8 | //sliding window approach 9 | 10 | const results = []; 11 | let windowSum = 0; 12 | let windowStart = 0; 13 | 14 | for (let windowEnd = 0; windowEnd < arr.length; windowEnd++) { 15 | //add the next element 16 | windowSum += arr[windowEnd]; 17 | 18 | //slide the window forward 19 | //we don't need to slide if we have not hit the required window size of k 20 | 21 | if (windowEnd >= k - 1) { 22 | //we are **AUTOMATICALLY** returning the window average once we hit the window size of k 23 | //and pushing to the output array 24 | results.push(windowSum / k); 25 | 26 | //subtracting the element going out 27 | windowSum -= arr[windowStart]; 28 | 29 | //then sliding the window forward 30 | windowStart++; 31 | 32 | //adding the element coming in, in the outer/previous loop 33 | //and repeating this process until we hit the end of the array 34 | } 35 | } 36 | return results; 37 | } 38 | 39 | findAveragesOfSubarrays([1, 3, 2, 6, -1, 4, 1, 8, 2], 5); //[2.2, 2.8, 2.4, 3.6, 2.8] 40 | -------------------------------------------------------------------------------- /leetcode/Palindrome-LinkedList-ts/README.md: -------------------------------------------------------------------------------- 1 | ## 234. PALINDROME LINKED LIST 2 | 3 | Given the head of a singly linked list, return true if it is a palindrome. 4 | 5 | ### Example 1: 6 | 7 | Input: head = [1,2,2,1] 8 | Output: true 9 | 10 | ### Problem Link: 11 | 12 | [Palindrome Linked List](https://leetcode.com/problems/palindrome-linked-list/) 13 | 14 | ### Solution: 15 | 16 | #### TypeScript 17 | 18 | ```typescript 19 | const listValues = (head: ListNode | null): number[] => { 20 | const elements: number[] = []; 21 | let curNode = head; 22 | while (curNode) { 23 | elements.push(curNode.val); 24 | curNode = curNode.next; 25 | } 26 | return elements; 27 | }; 28 | 29 | function isPalindrome(head: ListNode | null): boolean { 30 | let values = listValues(head); 31 | let i = 0; 32 | let j = values.length - 1; 33 | while (i < j) { 34 | if (values[i] !== values[j]) return false; 35 | i++; 36 | j--; 37 | } 38 | return true; 39 | } 40 | ``` 41 | 42 | ### Complexity Analysis: 43 | 44 | - Time Complexity: O(n) 45 | - Space Complexity: O(n) 46 | - Runtime: 104 ms 47 | -------------------------------------------------------------------------------- /leetcode/Palindrome-LinkedList-ts/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * class ListNode { 4 | * val: number 5 | * next: ListNode | null 6 | * constructor(val?: number, next?: ListNode | null) { 7 | * this.val = (val===undefined ? 0 : val) 8 | * this.next = (next===undefined ? null : next) 9 | * } 10 | * } 11 | */ 12 | class ListNode { 13 | val: number 14 | next: ListNode | null 15 | constructor(val?: number, next?: ListNode | null) { 16 | this.val = (val === undefined ? 0 : val) 17 | this.next = (next === undefined ? null : next) 18 | } 19 | } 20 | 21 | const listValues = (head: ListNode | null): number[] => { 22 | const elements: number[] = []; 23 | let curNode = head; 24 | while (curNode) { 25 | elements.push(curNode.val); 26 | curNode = curNode.next; 27 | } 28 | return elements; 29 | } 30 | 31 | function isLikedListPalindrome(head: ListNode | null): boolean { 32 | let values = listValues(head); 33 | let i = 0; 34 | let j = values.length - 1; 35 | while (i < j) { 36 | if (values[i] !== values[j]) return false 37 | i++; 38 | j--; 39 | } 40 | return true 41 | }; -------------------------------------------------------------------------------- /leetcode/README.md: -------------------------------------------------------------------------------- 1 | ## WELCOME TO LEETCODE DSA PROBLEMS SOLUTIONS IN TYPESCRIPT 2 | 3 | This repository contains the solutions to Data Structures and algorithms (DSA) problems in Leetcode. 4 | The solutions are written in Typescript. 5 | 6 | ## Contribution 7 | To contribute, create a new folder with the name of the problem in this directory. 8 | 9 | 10 | -------------------------------------------------------------------------------- /leetcode/Sorting the Sentence-js/README.md: -------------------------------------------------------------------------------- 1 | ## LeetCode - Sorting the Sentence 2 | 3 | A sentence is a list of words that are separated by a single space with no leading or trailing spaces. Each word consists of lowercase and uppercase English letters. 4 | 5 | A sentence can be shuffled by appending the 1-indexed word position to each word then rearranging the words in the sentence. 6 | 7 | For example, the sentence "This is a sentence" can be shuffled as "sentence4 a3 is2 This1" or "is2 sentence4 This1 a3". 8 | 9 | 10 | **Problem Source:** [LeetCode](https://leetcode.com/problems/sorting-the-sentence/) 11 | 12 | 13 | ## TEST CASES 14 | ```javascript 15 | // TEST CASE 1 16 | sortSentence("Myself2 Me1 I4 and3"); //Me Myself and I 17 | 18 | // TEST CASE 2 19 | sortSentence("is2 sentence4 This1 a3"); // This is a sentence 20 | 21 | // TEST CASE 3 22 | sortSentence('I1 am3 nice2 guy4')// I nice am guy 23 | 24 | ``` 25 | ## Time Complexity 26 | **O(n^2)** 27 | 28 | ## Space Complexity 29 | **O(1)** 30 | -------------------------------------------------------------------------------- /leetcode/Sorting the Sentence-js/index.js: -------------------------------------------------------------------------------- 1 | var sortSentence = function (s) { 2 | return s 3 | .split(" ") 4 | .sort((a, b) => { 5 | return a[a.length - 1] - b[b.length - 1]; 6 | }) 7 | .map((word) => { 8 | return word.slice(0, -1); 9 | }) 10 | .join(" "); 11 | }; -------------------------------------------------------------------------------- /leetcode/Unique Number of Occurrences - js/README.md: -------------------------------------------------------------------------------- 1 | ## Unique Number of Occurrences 2 | Given an array of integers arr, return true if the number of occurrences of each value in the array is unique, or false otherwise. 3 | 4 | **Problem Source:** [LeetCode](https://leetcode.com/problems/unique-number-of-occurrences/) 5 | 6 | **Difficulty:** Easy 7 | 8 | **Tags:** Array, Hash Map, Set 9 | 10 | 11 | ## TEST CASES 12 | ```javascript 13 | // TEST CASE 1 14 | console.log(uniqueOccurrences([1,2,2,1,1,3])) // true 15 | 16 | // TEST CASE 2 17 | console.log(uniqueOccurrences([3, 2, 4])) // false 18 | 19 | // TEST CASE 3 20 | console.log(uniqueOccurrences([-3,0,1,-3,1,1,1,-3,10,0])) // true 21 | ``` 22 | ## Time Complexity 23 | **O(n)** 24 | 25 | ## Space Complexity 26 | **O(1)** 27 | -------------------------------------------------------------------------------- /leetcode/Unique Number of Occurrences - js/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} arr 3 | * @return {boolean} 4 | */ 5 | var uniqueOccurrences = function(arr) { 6 | let map = new Map(); 7 | let set = new Set(); 8 | 9 | for(var num of arr) { 10 | if(map.has(num)) { 11 | map.set(num, map.get(num) + 1); 12 | } else{ 13 | map.set(num, 1); 14 | } 15 | 16 | } 17 | for(var freq of map.values()) { 18 | if(set.has(freq)) return false; 19 | set.add(freq); 20 | } 21 | 22 | return true; 23 | }; -------------------------------------------------------------------------------- /leetcode/absolute-k-diff-ts/README.md: -------------------------------------------------------------------------------- 1 | ## LeetCode - Absolute K Diff TS 2 | 3 | ### Problem Statement 4 | 5 | Given an array of integers `nums` and an integer `k`, return the number of pairs `(i, j)` where `i < j` such that `|nums[i] - nums[j]| == k`. 6 | 7 | The value of |x| is defined as: 8 | 9 | x if x >= 0. 10 | -x if x < 0. 11 | 12 | 13 | **Example 1:** 14 | 15 | Input: nums = [1,2,2,1], k = 1 16 | Output: 4 17 | Explanation: The pairs with an absolute difference of 1 are: 18 | - [1,2,2,1] 19 | - [1,2,2,1] 20 | - [1,2,2,1] 21 | - [1,2,2,1] 22 | 23 | **Example 2:** 24 | 25 | Input: nums = [1,3], k = 3 26 | Output: 0 27 | Explanation: There are no pairs with an absolute difference of 3. 28 | Example 3: 29 | 30 | Input: nums = [3,2,1,5,4], k = 2 31 | Output: 3 32 | Explanation: The pairs with an absolute difference of 2 are: 33 | - [3,2,1,5,4] 34 | - [3,2,1,5,4] 35 | - [3,2,1,5,4] 36 | 37 | 38 | **Problem Source:** [LeetCode](https://leetcode.com/problems/count-number-of-pairs-with-absolute-difference-k/) 39 | 40 | 41 | ## TEST CASES 42 | ```javascript 43 | // TEST CASE 1 44 | const nums = [1,2,2,1]; 45 | const k = 1; 46 | const output = 4; 47 | 48 | // TEST CASE 2 49 | const nums = [1,3]; 50 | const k = 3; 51 | const output = 0; 52 | 53 | // TEST CASE 3 54 | const nums = [3,2,1,5,4]; 55 | const k = 2; 56 | const output = 3; 57 | ``` 58 | ## Time Complexity 59 | **O(n^2)** 60 | 61 | ## Space Complexity 62 | **O(1)** 63 | -------------------------------------------------------------------------------- /leetcode/absolute-k-diff-ts/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param nums : number[] 4 | * @param k : number 5 | * @returns number 6 | */ 7 | 8 | function countKDifference(nums: number[], k: number): number { 9 | let count = 0; 10 | for(let i = 0; i < nums.length; i++){ 11 | for(let j = i+1; j < nums.length; j++){ 12 | if(Math.abs(nums[i] - nums[j]) == k){ 13 | count++; 14 | } 15 | } 16 | } 17 | return count; 18 | } -------------------------------------------------------------------------------- /leetcode/add-two-numbers-ts/README.md: -------------------------------------------------------------------------------- 1 | ## LeetCode - Two Sum 2 | You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list. 3 | 4 | You may assume the two numbers do not contain any leading zero, except the number 0 itself. 5 | 6 | **Problem Source:** [LeetCode](https://leetcode.com/problems/add-two-numbers/) 7 | 8 | 9 | ## TEST CASES 10 | ```javascript 11 | // TEST CASE 1 12 | console.log(addTwoNumbers([2,4,3], [5,6,4])) // [7,0,8] 13 | 14 | // TEST CASE 2 15 | console.log(addTwoNumbers([0], [0])) // [0] 16 | 17 | // TEST CASE 3 18 | console.log(addTwoNumbers([9,9,9,9,9,9,9], [9,9,9,9])) // [8,9,9,9,0,0,0,1] 19 | ``` 20 | 21 | ## Time Complexity 22 | **O(max(m, n))** 23 | 24 | ## Space Complexity 25 | **O(max(m, n))** 26 | 27 | -------------------------------------------------------------------------------- /leetcode/add-two-numbers-ts/index.ts: -------------------------------------------------------------------------------- 1 | // You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list. 2 | 3 | // You may assume the two numbers do not contain any leading zero, except the number 0 itself. 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * class ListNode { 8 | * val: number 9 | * next: ListNode | null 10 | * constructor(val?: number, next?: ListNode | null) { 11 | * this.val = (val===undefined ? 0 : val) 12 | * this.next = (next===undefined ? null : next) 13 | * } 14 | * } 15 | */ 16 | 17 | class ListNode { 18 | val: number 19 | next: ListNode | null 20 | constructor(val?: number, next?: ListNode | null) { 21 | this.val = val === undefined ? 0 : val 22 | this.next = next === undefined ? null : next 23 | } 24 | } 25 | 26 | function addTwoNumbers( 27 | l1: ListNode | null, 28 | l2: ListNode | null 29 | ): ListNode | null { 30 | return add(l1, l2, 0) 31 | 32 | function add( 33 | l1: ListNode | null, 34 | l2: ListNode | null, 35 | carried: number 36 | ): ListNode | null { 37 | const value1 = (l1 && l1.val) || 0 38 | const value2 = (l2 && l2.val) || 0 39 | const sum = value1 + value2 + carried 40 | const carry = Math.floor(sum / 10) 41 | 42 | if (l1 || l2 || carried) { 43 | return { 44 | val: sum % 10, 45 | next: add(l1 && l1.next, l2 && l2.next, carry), 46 | } 47 | } 48 | return null 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /leetcode/house-robber-ts/README.md: -------------------------------------------------------------------------------- 1 | ## LEETCODE - House Robber II - TypeScript 2 | 3 | ### CHALLENGE 4 | 5 | You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security systems connected and it will automatically contact the police if two adjacent houses were broken into on the same night. 6 | 7 | Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police. 8 | 9 | ### PROBLEM SOURCE 10 | 11 | [LeetCode](https://leetcode.com/problems/house-robber-ii/) 12 | 13 | ### TEST CASES 14 | 15 | ```javascript 16 | // TEST CASE 1 17 | console.log(rob([2,3,2])) // 3 18 | 19 | // TEST CASE 2 20 | console.log(rob([1,2,3])) // 3 21 | 22 | // TEST CASE 3 23 | console.log(rob([1, 2, 3, 1])) // 4 24 | 25 | ``` 26 | 27 | ### SOLUTION 28 | 29 | ```javascript 30 | const rob = (nums: number[]): number => { 31 | // since nums[0] and nums[nums.length - 1] are adjacent, we can't rob both of them 32 | // so we rob 0 to nums.length - 2 or 1 to nums.length - 1 and take the max 33 | return Math.max(robRange(nums, 0, nums.length - 2), robRange(nums, 1, nums.length - 1)); 34 | } 35 | 36 | const robRange = (nums: number[], start: number, end: number): number => { 37 | let first = nums[start]; 38 | let second = Math.max(nums[start], nums[start + 1]); 39 | for (let i = start + 2; i <= end; i++) { 40 | let temp = second; 41 | second = Math.max(first + nums[i], second); 42 | first = temp; 43 | } 44 | return second; 45 | } 46 | ``` 47 | 48 | ### ANALYSIS 49 | 50 | #### Time Complexity 51 | 52 | **O(n)** 53 | 54 | #### Space Complexity 55 | 56 | **O(1)** 57 | 58 | #### Runtime: 80 ms 59 | -------------------------------------------------------------------------------- /leetcode/house-robber-ts/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. 3 | * All houses at this place are arranged in a circle. 4 | * That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have a security system connected, 5 | * and it will automatically contact the police if two adjacent houses were broken into on the same night. 6 | * Given an integer array nums representing the amount of money of each house, 7 | * return the maximum amount of money you can rob tonight without alerting the police. 8 | */ 9 | 10 | const rob = (nums: number[]): number => { 11 | // if there is only one house, return the money in that house 12 | if (nums.length === 1) return nums[0]; 13 | 14 | // if there are two houses, return the max of the two houses 15 | if (nums.length === 2) return Math.max(nums[0], nums[1]); 16 | 17 | // since nums[0] and nums[nums.length - 1] are adjacent, we can't rob both of them 18 | // so we rob 0 to nums.length - 2 or 1 to nums.length - 1 and take the max 19 | return Math.max(robRange(nums, 0, nums.length - 2), robRange(nums, 1, nums.length - 1)); 20 | } 21 | 22 | const robRange = (nums: number[], start: number, end: number): number => { 23 | let first = nums[start]; 24 | let second = Math.max(nums[start], nums[start + 1]); 25 | for (let i = start + 2; i <= end; i++) { 26 | let temp = second; 27 | second = Math.max(first + nums[i], second); 28 | first = temp; 29 | } 30 | return second; 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /leetcode/maximu-69-number-ts/README.md: -------------------------------------------------------------------------------- 1 | ## LEETCODE - 1323. Maximum 69 Number - TypeScript 2 | 3 | ### Problem 4 | Given a positive integer num consisting only of digits 6 and 9. Return the maximum number you can get by changing at most one digit (6 becomes 9, and 9 becomes 6). 5 | 6 | ### Example 1 7 | ``` 8 | Input: num = 9669 9 | Output: 9969 10 | Explanation: 11 | Changing the first digit results in 6669. 12 | Changing the second digit results in 9969. 13 | Changing the third digit results in 9699. 14 | Changing the fourth digit results in 9666. 15 | The maximum number is 9969. 16 | ``` 17 | 18 | ## Problem Source 19 | [1323. Maximum 69 Number](https://leetcode.com/problems/maximum-69-number/) - LeetCode 20 | 21 | ## Solution 22 | ```typescript 23 | function maximum69Number (num: number): number { 24 | const str = num.toString(); 25 | for (let i = 0; i < str.length; i++) { 26 | if (str[i] === '6') { 27 | return parseInt(str.slice(0, i) + '9' + str.slice(i + 1)); 28 | } 29 | } 30 | return num; 31 | }; 32 | ``` 33 | 34 | ## Test Cases 35 | ``` 36 | input: 9669 37 | output: 9969 38 | ``` 39 | 40 | ## Complexity 41 | - Time Complexity: O(n) 42 | - Space Complexity: O(n) 43 | 44 | -------------------------------------------------------------------------------- /leetcode/maximu-69-number-ts/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} num 3 | * @return {number} 4 | * @description 👇 5 | * Given a positive integer num consisting only of digits 6 and 9. 6 | * Return the maximum number you can get by changing at most one digit (6 becomes 9, and 9 becomes 6). 7 | */ 8 | function maximum69Number (num: number): number { 9 | const arr = num.toString().split(''); 10 | for (let i = 0; i < arr.length; i++) { 11 | if (arr[i] === '6') { 12 | arr[i] = '9'; 13 | break; 14 | } 15 | } 16 | return parseInt(arr.join('')); 17 | 18 | } -------------------------------------------------------------------------------- /leetcode/median-sorted-arr-ts/README.md: -------------------------------------------------------------------------------- 1 | ## LEETCODE 4. Median of Two Sorted Arrays 2 | 3 | ### Problem 4 | 5 | Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. 6 | 7 | Follow up: The overall run time complexity should be O(log (m+n)). 8 | 9 | ### Problem Source 10 | [Leetcode](https://leetcode.com/problems/median-of-two-sorted-arrays/) 11 | 12 | ### Solution 13 | 14 | ```typescript 15 | /** 16 | * 17 | * @param nums1 18 | * @param nums2 19 | * @returns 20 | */ 21 | 22 | function findMedianSortedArrays(nums1: number[], nums2: number[]): number { 23 | const merged = merge(nums1, nums2) 24 | const mid = Math.floor(merged.length / 2) 25 | if (merged.length % 2 === 0) { 26 | return (merged[mid] + merged[mid - 1]) / 2 27 | } 28 | return merged[mid] 29 | } 30 | 31 | /** 32 | * 33 | * @param nums1 34 | * @param nums2 35 | * @returns 36 | */ 37 | function merge(nums1: number[], nums2: number[]): number[] { 38 | const merged:number[] = [] 39 | let i = 0 40 | let j = 0 41 | while (i < nums1.length || j < nums2.length) { 42 | if (i === nums1.length) { 43 | merged.push(nums2[j]) 44 | j++ 45 | } else if (j === nums2.length) { 46 | merged.push(nums1[i]) 47 | i++ 48 | } else if (nums1[i] < nums2[j]) { 49 | merged.push(nums1[i]) 50 | i++ 51 | } else { 52 | merged.push(nums2[j]) 53 | j++ 54 | } 55 | } 56 | return merged 57 | } 58 | 59 | ``` 60 | 61 | ### Solution Analysis 62 | 63 | Time Complexity: O(n + m) 64 | 65 | Space Complexity: O(n + m) 66 | 67 | 68 | -------------------------------------------------------------------------------- /leetcode/median-sorted-arr-ts/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param nums1 4 | * @param nums2 5 | * @returns 6 | */ 7 | 8 | function findMedianSortedArrays(nums1: number[], nums2: number[]): number { 9 | const merged = merge(nums1, nums2) 10 | const mid = Math.floor(merged.length / 2) 11 | if (merged.length % 2 === 0) { 12 | return (merged[mid] + merged[mid - 1]) / 2 13 | } 14 | return merged[mid] 15 | } 16 | 17 | /** 18 | * 19 | * @param nums1 20 | * @param nums2 21 | * @returns 22 | */ 23 | function merge(nums1: number[], nums2: number[]): number[] { 24 | const merged:number[] = [] 25 | let i = 0 26 | let j = 0 27 | while (i < nums1.length || j < nums2.length) { 28 | if (i === nums1.length) { 29 | merged.push(nums2[j]) 30 | j++ 31 | } else if (j === nums2.length) { 32 | merged.push(nums1[i]) 33 | i++ 34 | } else if (nums1[i] < nums2[j]) { 35 | merged.push(nums1[i]) 36 | i++ 37 | } else { 38 | merged.push(nums2[j]) 39 | j++ 40 | } 41 | } 42 | return merged 43 | } 44 | -------------------------------------------------------------------------------- /leetcode/move-zeroes-js/README.md: -------------------------------------------------------------------------------- 1 | ## LeetCode - Move Zeroes 2 | Given an integer array nums, move all 0's to the end of it 3 | while maintaining the relative order of the non-zero elements. 4 | Note that you must do this in-place without making a copy of the array. 5 | 6 | 7 | **Problem Source:** [LeetCode](https://leetcode.com/problems/move-zeroes/) 8 | 9 | 10 | ## TEST CASES 11 | ```javascript 12 | // TEST CASE 1 13 | console.log(moveZeroes([0,1,0,3,12])) // [1,3,12,0,0] 14 | 15 | // TEST CASE 2 16 | console.log(moveZeroes([0, 1, 0, 3, 6, 0])) // [1,3,6,0,0,0] 17 | 18 | // TEST CASE 3 19 | console.log(moveZeroes([0, 2, 8, 3, 0, 3, 0])) // [2,8,3,3,0,0,0] 20 | 21 | ``` 22 | ## Time Complexity 23 | **O(n)** 24 | 25 | ## Space Complexity 26 | **O(1)** 27 | -------------------------------------------------------------------------------- /leetcode/move-zeroes-js/index.js: -------------------------------------------------------------------------------- 1 | var moveZeroes = function (nums) { 2 | let low = 0; 3 | let high = low + 1; 4 | while (high <= nums.length - 1) { 5 | if (nums[low] !== 0) { 6 | low++; 7 | high++; 8 | } else { 9 | if (nums[high] !== 0) { 10 | [nums[low], nums[high]] = [nums[high], nums[low]]; 11 | low++; 12 | } 13 | high++; 14 | } 15 | } 16 | return nums; 17 | }; 18 | -------------------------------------------------------------------------------- /leetcode/orderly-queue-ts/README.md: -------------------------------------------------------------------------------- 1 | ## LEETCODE - Orderly Queue - TypeScript 2 | 3 | ### CHALLENGE 4 | You are given a string s and an integer k. You can choose one of the first k letters of s and append it at the end of the string.. 5 | Return the lexicographically smallest string you could have after applying the mentioned step any number of moves. 6 | 7 | ### PROBLEM SOURCE 8 | [LeetCode](https://leetcode.com/problems/orderly-queue/) 9 | 10 | ### TEST CASES 11 | ```javascript 12 | // TEST CASE 1 13 | console.log(orderlyQueue("cba", 1)) // "acb" 14 | 15 | // TEST CASE 2 16 | console.log(orderlyQueue("baaca", 3)) // "aaabc" 17 | 18 | // TEST CASE 3 19 | console.log(orderlyQueue("baaca", 1)) // "aaabc" 20 | 21 | ``` 22 | 23 | ### SOLUTION 24 | 25 | ```javascript 26 | const orderlyQueue = (s: string, k: number): string => { 27 | // if k > 1, we can reorder the string to get the lexicographically smallest string 28 | if (k > 1) return s.split('').sort().join(''); 29 | 30 | // if k === 1, we can only rotate the string to get the lexicographically smallest string 31 | let result = s; 32 | for (let i = 0; i < s.length; i++) { 33 | let temp = s.slice(i) + s.slice(0, i); 34 | if (temp < result) result = temp; 35 | } 36 | return result; 37 | }; 38 | ``` 39 | 40 | ### ANALYSIS 41 | 42 | #### Time Complexity 43 | 44 | **O(n^2) or O(nlogn)** 45 | - if k > 1, we sort the string which takes O(nlogn) time 46 | - if k === 1, we rotate the string n times which takes O(n^2) time 47 | - in the worst case, we have k === 1 and n === 100, so the time complexity is O(n^2) 48 | - in the best case, we have k > 1 and n === 100, so the time complexity is O(nlogn) 49 | - in the average case, we have k === 1 and n === 100, so the time complexity is O(n^2) 50 | 51 | #### Space Complexity 52 | 53 | **O(n)** 54 | - we create a new string for each rotation, so the space complexity is O(n) 55 | - in the worst case, we have k === 1 and n === 100, so the space complexity is O(n) 56 | - in the best case, we have k > 1 and n === 100, so the space complexity is O(n) 57 | - in the average case, we have k === 1 and n === 100, so the space complexity is O(n) 58 | 59 | 60 | #### Runtime: 80 ms -------------------------------------------------------------------------------- /leetcode/orderly-queue-ts/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param s The string s 4 | * @param k The number k 5 | * @returns The lexicographically smallest string you could have after applying the mentioned step any number of moves. 6 | */ 7 | const orderlyQueue = (s: string, k: number): string => { 8 | // if k > 1, we can reorder the string to get the lexicographically smallest string 9 | if (k > 1) return s.split('').sort().join(''); 10 | 11 | // if k === 1, we can only rotate the string to get the lexicographically smallest string 12 | let result = s; 13 | for (let i = 0; i < s.length; i++) { 14 | let temp = s.slice(i) + s.slice(0, i); 15 | if (temp < result) result = temp; 16 | } 17 | return result; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /leetcode/palindrome-number-js/README.md: -------------------------------------------------------------------------------- 1 | ## LeetCode - Palindrome number 2 | Given an integer x, return true if x is palindrome integer. 3 | An integer is a palindrome when it reads the same backward as forward. 4 | For example, 121 is a palindrome while 123 is not. 5 | 6 | 7 | **Problem Source:** [LeetCode](https://leetcode.com/problems/palindrome-number/) 8 | 9 | 10 | ## TEST CASES 11 | ```javascript 12 | // TEST CASE 1 13 | console.log(isPalindrome(121)) // true 14 | 15 | // TEST CASE 2 16 | console.log(isPalindrome(221)) // false 17 | 18 | // TEST CASE 3 19 | console.log(isPalindrome(331)) // false 20 | 21 | // TEST CASE 4 22 | console.log(isPalindrome(414)) // true 23 | ``` 24 | ## Time Complexity 25 | **O(n)** 26 | 27 | ## Space Complexity 28 | **O(1)** 29 | -------------------------------------------------------------------------------- /leetcode/palindrome-number-js/index.js: -------------------------------------------------------------------------------- 1 | var isPalindrome = function(x) { 2 | let reversedX = x.toString().split('').reverse().join(''); 3 | if(Math.floor(reversedX) === x) { 4 | return true; 5 | } else { 6 | return false; 7 | } 8 | }; -------------------------------------------------------------------------------- /leetcode/plus-one-js/README.md: -------------------------------------------------------------------------------- 1 | ## LeetCode - Plus one 2 | You are given a large integer represented as an integer array digits, where each digits[i] is the ith digit of the integer. The digits are ordered from most significant to least significant in left-to-right order. The large integer does not contain any leading 0's. 3 | 4 | Increment the large integer by one and return the resulting array of digits. 5 | 6 | 7 | **Problem Source:** [LeetCode](https://leetcode.com/problems/plus-one/) 8 | 9 | 10 | ## TEST CASES 11 | ```javascript 12 | // TEST CASE 1 13 | console.log(plusOne([1, 2, 3])) // [1, 2, 4] 14 | 15 | // TEST CASE 2 16 | console.log(plusOne([9])) // [1, 0] 17 | 18 | // TEST CASE 3 19 | console.log(plusOne([9, 9])) // [1, 0, 1, 0] 20 | 21 | // TEST CASE 4 22 | console.log(plusOne([3, 7, 9, 9])) // [3, 8, 0, 0] 23 | ``` 24 | ## Time Complexity 25 | **O(1)** 26 | 27 | ## Space Complexity 28 | **O(1)** 29 | -------------------------------------------------------------------------------- /leetcode/plus-one-js/index.js: -------------------------------------------------------------------------------- 1 | var plusOne = function(digits) { 2 | let str = digits.join(''); 3 | let num = BigInt(str) + BigInt(1); 4 | return num.toString().split('').map(str => parseInt(str)); 5 | }; -------------------------------------------------------------------------------- /leetcode/reverse-integer-ts/README.md: -------------------------------------------------------------------------------- 1 | ## LEETCODE - Reverse Integer - TypeScript 2 | ### CHALLENGE 3 | Given a signed 32-bit integer x, return x with its digits reversed. If reversing x causes the value to go outside the signed 32-bit integer range [-231, 231 - 1], then return 0. 4 | 5 | **Assume the environment does not allow you to store 64-bit integers (signed or unsigned).** 6 | 7 | ### PROBLEM SOURCE 8 | [LeetCode](https://leetcode.com/problems/reverse-integer/) 9 | 10 | ### TEST CASES 11 | ```javascript 12 | // TEST CASE 1 13 | console.log(reverse(123)) // 321 14 | 15 | // TEST CASE 2 16 | console.log(reverse(-123)) // -321 17 | 18 | // TEST CASE 3 19 | console.log(reverse(1534236469)) // 0 20 | 21 | // TEST CASE 4 22 | 23 | console.log(reverse(120)) // 21 24 | ``` 25 | ### SOLUTION 26 | ```javascript 27 | function reverse(x: number): number { 28 | const isNegative: boolean = x < 0; 29 | const xstring: string = x.toString() 30 | const reversedxString: string[] = [] 31 | for (let i = xstring.length - 1; i >= 0; i--) { 32 | reversedxString.push(xstring[i]); 33 | } 34 | const revNum = parseInt(reversedxString.join('')); 35 | if (revNum > Math.pow(2, 31)) return 0; 36 | return isNegative ? -revNum : revNum; 37 | } 38 | ``` 39 | ### ANALYSIS 40 | 41 | #### Time Complexity 42 | **O(n)** 43 | 44 | #### Space Complexity 45 | **O(1)** 46 | 47 | #### Runtime: 88 ms 48 | -------------------------------------------------------------------------------- /leetcode/reverse-integer-ts/index.ts: -------------------------------------------------------------------------------- 1 | function reverse(x: number): number { 2 | const isNegative: boolean = x < 0; 3 | const xstring: string = x.toString() 4 | const reversedxString: string[] = [] 5 | for (let i = xstring.length - 1; i >= 0; i--) { 6 | reversedxString.push(xstring[i]); 7 | } 8 | const revNum = parseInt(reversedxString.join('')); 9 | if (revNum > Math.pow(2, 31)) return 0; 10 | return isNegative ? -revNum : revNum; 11 | }; 12 | 13 | console.log(reverse(1534236469)); 14 | // Time Complexity: O(n) 15 | // Space Complexity: O(n) -------------------------------------------------------------------------------- /leetcode/reverse-vowels-ts/README.md: -------------------------------------------------------------------------------- 1 | ## LEETCODE - REVERSE VOWELS IN A STRING 2 | 3 | ### CHALLENGE 4 | Given a string s, reverse only all the vowels in the string and return it. 5 | The vowels are 'a', 'e', 'i', 'o', and 'u', and they can appear in both lower and upper cases, more than once. 6 | 7 | ### PROBLEM SOURCE 8 | [LeetCode](https://leetcode.com/problems/reverse-vowels-of-a-string/) 9 | 10 | ### TEST CASES 11 | ```javascript 12 | // TEST CASE 1 13 | console.log(reverseVowels('hello')) // 'holle' 14 | 15 | // TEST CASE 2 16 | console.log(reverseVowels('leetcode')) // 'leotcede' 17 | 18 | // TEST CASE 3 19 | console.log(reverseVowels('aA')) // 'Aa' 20 | ``` 21 | ### SOLUTION 22 | ```javascript 23 | function reverseVowels(s: string): string { 24 | const vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'] 25 | const sArr = s.split('') 26 | let left = 0 27 | let right = sArr.length - 1 28 | while (left < right) { 29 | if (vowels.includes(sArr[left]) && vowels.includes(sArr[right])) { 30 | const temp = sArr[left] 31 | sArr[left] = sArr[right] 32 | sArr[right] = temp 33 | left++ 34 | right-- 35 | } else if (vowels.includes(sArr[left])) { 36 | right-- 37 | } else if (vowels.includes(sArr[right])) { 38 | left++ 39 | } else { 40 | left++ 41 | right-- 42 | } 43 | } 44 | return sArr.join('') 45 | } 46 | ``` 47 | ### ANALYSIS 48 | #### Time Complexity 49 | **O(n)** 50 | #### Space Complexity 51 | **O(1)** 52 | #### Runtime: 104 ms -------------------------------------------------------------------------------- /leetcode/reverse-vowels-ts/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param s string to reverse vowels 4 | * @returns string with vowels reversed 5 | */ 6 | 7 | 8 | function reverseVowels(s: string): string { 9 | const vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']; 10 | const s2arr = s.split(''); 11 | let left = 0; 12 | let right = s2arr.length - 1; 13 | while (left < right) { 14 | if (vowels.includes(s2arr[left]) && vowels.includes(s2arr[right])) { 15 | const temp = s2arr[left]; 16 | s2arr[left] = s2arr[right]; 17 | s2arr[right] = temp; 18 | left++; 19 | right--; 20 | } else if (vowels.includes(s2arr[left])) { 21 | right--; 22 | } else { 23 | left++; 24 | } 25 | } 26 | return s2arr.join(''); 27 | } 28 | 29 | // Time Complexity: O(n) 30 | // Space Complexity: O(n) -------------------------------------------------------------------------------- /leetcode/roman-to-int-ts/README.md: -------------------------------------------------------------------------------- 1 | ## LeetCode - Roman to Integer 2 | Given a roman numeral, convert it to an integer. 3 | 4 | 5 | **Problem Source:** [LeetCode](https://leetcode.com/problems/roman-to-integer/) 6 | 7 | 8 | ## TEST CASES 9 | ```javascript 10 | // TEST CASE 1 11 | console.log(romanToInt('iii')) // 3 12 | 13 | // TEST CASE 2 14 | console.log(romanToInt('IV')) // 4 15 | 16 | // TEST CASE 3 17 | console.log(romanToInt('Ix')) // 9 18 | 19 | // TEST CASE 4 20 | console.log(romanToInt('LVIiI')) // 58 21 | ``` 22 | ## Time Complexity 23 | **O(n)** 24 | 25 | ## Space Complexity 26 | **O(1)** 27 | -------------------------------------------------------------------------------- /leetcode/roman-to-int-ts/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param s: string 4 | * @returns result: number 5 | */ 6 | 7 | function romanToInt(s: string): number { 8 | s = s.toUpperCase() 9 | let result:number = 0 10 | 11 | for (let i = 0; i < s.length; i++) { 12 | switch (s[i]) { 13 | case 'I': 14 | if (s[i + 1] === 'V') { 15 | result += 4 16 | i++ 17 | } else if (s[i + 1] === 'X') { 18 | result += 9 19 | i++ 20 | } else { 21 | result += 1 22 | } 23 | break 24 | case 'V': 25 | result += 5 26 | break 27 | case 'X': 28 | if (s[i + 1] === 'L') { 29 | result += 40 30 | i++ 31 | } else if (s[i + 1] === 'C') { 32 | result += 90 33 | i++ 34 | } else { 35 | result += 10 36 | } 37 | break 38 | case 'L': 39 | result += 50 40 | break 41 | case 'C': 42 | if (s[i + 1] === 'D') { 43 | result += 400 44 | i++ 45 | } else if (s[i + 1] === 'M') { 46 | result += 900 47 | i++ 48 | } else { 49 | result += 100 50 | } 51 | break 52 | case 'D': 53 | result += 500 54 | break 55 | case 'M': 56 | result += 1000 57 | break 58 | } 59 | } 60 | 61 | return result 62 | } 63 | -------------------------------------------------------------------------------- /leetcode/substring-without-rep-ts/README.md: -------------------------------------------------------------------------------- 1 | ## Leetcode - 3. Longest Substring Without Repeating Characters 2 | 3 | ### Problem Statement 4 | Given a string s, find the length of the longest substring without repeating characters. 5 | 6 | ### Example 1: 7 | ``` 8 | Input: s = "abcabcbb" 9 | Output: 3 10 | Explanation: The answer is "abc", with the length of 3. 11 | ``` 12 | 13 | ### Example 2: 14 | ``` 15 | Input: s = "bbbbb" 16 | Output: 1 17 | Explanation: The answer is "b", with the length of 1. 18 | ``` 19 | 20 | ### Example 3: 21 | ``` 22 | Input: s = "pwwkew" 23 | Output: 3 24 | Explanation: The answer is "wke", with the length of 3. 25 | Notice that the answer must be a substring, "pwke" is a subsequence and not a substring. 26 | ``` 27 | 28 | ## Solution 29 | ```ts 30 | function lengthOfLongestSubstring(s: string): number { 31 | let longest = 0; 32 | let current = 0; 33 | let start = 0; 34 | let end = 0; 35 | const set = new Set(); 36 | while (end < s.length) { 37 | if (!set.has(s[end])) { 38 | set.add(s[end]); 39 | current++; 40 | end++; 41 | } else { 42 | set.delete(s[start]); 43 | current--; 44 | start++; 45 | } 46 | longest = Math.max(longest, current); 47 | } 48 | return longest; 49 | }; 50 | ``` 51 | 52 | ## Test Cases 53 | ``` 54 | "abcabcbb" 55 | "bbbbb" 56 | "pwwkew" 57 | "" 58 | " " 59 | "au" 60 | "dvdf" 61 | "abba" 62 | ``` 63 | 64 | ## Complexity Analysis 65 | - Time Complexity: O(n) 66 | - Space Complexity: O(n) 67 | - Runtime: 132 ms, faster than 98.98% of TypeScript online submissions for Longest Substring Without Repeating Characters. 68 | 69 | 70 | ## Tags 71 | - Set 72 | 73 | 74 | -------------------------------------------------------------------------------- /leetcode/substring-without-rep-ts/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param s 4 | * @returns 5 | */ 6 | function lengthOfLongestSubstring(s: string): number { 7 | let longest = 0; 8 | let current = 0; 9 | let start = 0; 10 | let end = 0; 11 | const set = new Set(); 12 | while (end < s.length) { 13 | if (!set.has(s[end])) { 14 | set.add(s[end]); 15 | current++; 16 | end++; 17 | } else { 18 | set.delete(s[start]); 19 | current--; 20 | start++; 21 | } 22 | longest = Math.max(longest, current); 23 | } 24 | return longest; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /leetcode/two-sum-ts/README.md: -------------------------------------------------------------------------------- 1 | ## LeetCode - Two Sum 2 | Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target. 3 | 4 | You may assume that each input would have exactly one solution, and you may not use the same element twice. 5 | 6 | You can return the answer in any order. 7 | 8 | **Problem Source:** [LeetCode](https://leetcode.com/problems/two-sum/) 9 | 10 | **Difficulty:** Easy 11 | 12 | **Tags:** Array, Hash Table 13 | 14 | **Reason for Update:** 15 | The original solution was not the most efficient. I have updated the solution to use a hash table to improve the efficiency. 16 | The time complexity is now O(n) and the space complexity is O(n). The original solution had a time complexity of O(n^2) and a space complexity of O(1). 17 | 18 | 19 | ## TEST CASES 20 | ```javascript 21 | // TEST CASE 1 22 | console.log(twoSum([2, 7, 11, 15, 8], 9)) // [0,1] 23 | 24 | // TEST CASE 2 25 | console.log(twoSum([3, 2, 4], 6)) // [1,2] 26 | 27 | // TEST CASE 3 28 | console.log(twoSum([3,2, 5, 7, 1, 5], 6)) // [2,4] 29 | ``` 30 | ## Time Complexity 31 | **O(n)** 32 | 33 | ## Space Complexity 34 | **O(n)** 35 | -------------------------------------------------------------------------------- /leetcode/two-sum-ts/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param nums: number[] 4 | * @param target: number 5 | * @returns result: number[] 6 | */ 7 | 8 | 9 | // two sums using map 10 | function twoSum(nums: number[], target: number): number[] { 11 | let map = new Map() 12 | for ( let i = 0; i < nums.length; i++){ 13 | let complement = target - nums[i] 14 | if (map.has(complement)) { 15 | return [map.get(complement), i] 16 | } 17 | map.set(nums[i], i) 18 | } 19 | return [] 20 | } 21 | -------------------------------------------------------------------------------- /leetcode/valid-palindrome-ts/README.md: -------------------------------------------------------------------------------- 1 | ## LEETCODE 125. Valid Palindrome - TypeScript 2 | 3 | ### Problem 4 | A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers. 5 | 6 | Given a string s, return true if it is a palindrome, or false otherwise. 7 | 8 | ### Example 9 | ``` 10 | Input: s = "A man, a plan, a canal: Panama" 11 | Output: true 12 | Explanation: "amanaplanacanalpanama" is a palindrome. 13 | ``` 14 | 15 | ### Constraints 16 | ``` 17 | 1 <= s.length <= 2 * 105 18 | s consists only of printable ASCII characters. 19 | ``` 20 | 21 | ## Problem Source 22 | [LeetCode 125. Valid Palindrome](https://leetcode.com/problems/valid-palindrome/) 23 | 24 | ## Solution 25 | ```typescript 26 | function isPalindrome(s: string): boolean { 27 | let i = 0; 28 | let j = s.length - 1; 29 | while (i < j) { 30 | if (!isAlphaNumeric(s[i])) { 31 | i++; 32 | continue; 33 | } 34 | if (!isAlphaNumeric(s[j])) { 35 | j--; 36 | continue; 37 | } 38 | if (s[i].toLowerCase() !== s[j].toLowerCase()) { 39 | return false; 40 | } 41 | i++; 42 | j--; 43 | } 44 | return true; 45 | }; 46 | 47 | function isAlphaNumeric(c: string): boolean { 48 | return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); 49 | } 50 | ``` 51 | 52 | ## Time Complexity 53 | **O(n)** 54 | 55 | ## Space Complexity 56 | **O(1)** 57 | 58 | -------------------------------------------------------------------------------- /leetcode/valid-palindrome-ts/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param s 4 | * @returns boolean 5 | */ 6 | 7 | function isPalindrome(s: string): boolean { 8 | let i = 0; 9 | let j = s.length - 1; 10 | while (i < j) { 11 | if (!isAlphaNumeric(s[i])) { 12 | i++; 13 | continue; 14 | } 15 | if (!isAlphaNumeric(s[j])) { 16 | j--; 17 | continue; 18 | } 19 | if (s[i].toLowerCase() !== s[j].toLowerCase()) { 20 | return false; 21 | } 22 | i++; 23 | j--; 24 | } 25 | return true; 26 | }; 27 | 28 | /** 29 | * 30 | * @param c 31 | * @returns boolean 32 | */ 33 | function isAlphaNumeric(c: string): boolean { 34 | return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); 35 | } 36 | --------------------------------------------------------------------------------