├── .gitignore ├── AddingNewSolutions.txt ├── LeetcodeQuestions ├── LeetcodeQuestions.sln └── SolutionNavigator │ ├── Header Files │ ├── 001 - twoSum.h │ ├── 002 - addTwoNumbers.h │ ├── 003 - longestSubstringWithoutRepeatingCharacters.h │ ├── 014 - longestCommonPrefix.h │ ├── 017 - letterCombinationsOfAPhoneNumber.h │ ├── 019 - removeNthNodeFromEndOfList.h │ ├── 020 - validParentheses.h │ ├── 021 - mergeTwoSortedLists.h │ ├── 022 - generateParentheses.h │ ├── 023 - mergeKSortedLists.h │ ├── 028 - implementStrstr.h │ ├── 033 - searchInRotatedSortedArray.h │ ├── 036 - validSudoku.h │ ├── 041 - firstMissingPositive.h │ ├── 045 - jumpGameII.h │ ├── 049 - groupAnagrams.h │ ├── 054 - spiralMatrix.h │ ├── 055 - jumpGame.h │ ├── 056 - mergeIntervals.h │ ├── 057 - insertInterval.h │ ├── 066 - plusOne.h │ ├── 070 - climbingStairs.h │ ├── 074 - searchA2DMatrix.h │ ├── 075 - sortColors.h │ ├── 078 - subsets.h │ ├── 086 - partitionList.h │ ├── 098 - validateBinarySearchTree.h │ ├── 100 - sameTree.h │ ├── 101 - symmetricTree.h │ ├── 102 - binaryTreeLevelOrderTraversal.h │ ├── 104 - maximumDepthOfBinaryTree.h │ ├── 111 - minimumDepthOfBinaryTree.h │ ├── 112 - pathSum.h │ ├── 113 - pathSumII.h │ ├── 114 - flattenBinaryTreeToLinkedList.h │ ├── 121 - bestTimeToBuyAndSellStock.h │ ├── 122 - bestTimeToBuyAndSellStockII.h │ ├── 124 - binaryTreeMaximumPathSum.h │ ├── 125 - validPalindrome.h │ ├── 129 - sumRootToLeafNumbers.h │ ├── 136 - singleNumber.h │ ├── 137 - singleNumberII.h │ ├── 141 - linkedListCycle.h │ ├── 142 - linkedListCycleII.h │ ├── 143 - reorderList.h │ ├── 144 - binaryTreePreorderTraversal.h │ ├── 145 - binaryTreePostorderTraversal.h │ ├── 153 - findMinimumInRotatedSortedArray.h │ ├── 155 - minStack.h │ ├── 162 - findPeakElement.h │ ├── 169 - majorityElement.h │ ├── 172 - factorialTrailingZeroes.h │ ├── 191 - numberOfOneBits.h │ ├── 198 - houseRobber.h │ ├── 200 - numberOfIslands.h │ ├── 202 - happyNumber.h │ ├── 206 - reverseLinkedList.h │ ├── 215 - kthLargestElementInAnArray.h │ ├── 217 - containsDuplicate.h │ ├── 226 - invertBinaryTree.h │ ├── 234 - palindromeLinkedList.h │ ├── 235 - lowestCommonAncestorOfABinarySearchTree.h │ ├── 236 - lowestCommonAncestorOfABinaryTree.h │ ├── 237 - deleteNodeInALinkedList.h │ ├── 238 - productOfArrayExceptSelf.h │ ├── 242 - validAnagram.h │ ├── 257 - binaryTreePaths.h │ ├── 258 - addDigits.h │ ├── 278 - firstBadVersion.h │ ├── 292 - nimGame.h │ ├── 293 - flipGame.h │ ├── 300 - longestIncreasingSubsequence.h │ ├── 328 - oddEvenLinkedList.h │ ├── 344 - reverseString.h │ ├── 412 - fizzBuzz.h │ ├── 419 - battleshipsInABoard.h │ ├── 461 - hammingDistance.h │ ├── 540 - singleElementInASortedArray.h │ ├── 617 - mergeTwoBinaryTrees.h │ ├── 657 - judgeRouteCircle.h │ └── config.h │ ├── Leetcode Source Files │ ├── 001 - twoSum.cpp │ ├── 002 - addTwoNumbers.cpp │ ├── 003 - longestSubstringWithoutRepeatingCharacters.cpp │ ├── 014 - longestCommonPrefix.cpp │ ├── 017 - letterCombinationsOfAPhoneNumber.cpp │ ├── 019 - removeNthNodeFromEndOfList.cpp │ ├── 020 - validParentheses.cpp │ ├── 021 - mergeTwoSortedLists.cpp │ ├── 022 - generateParentheses.cpp │ ├── 023 - mergeKSortedLists.cpp │ ├── 028 - implementStrstr.cpp │ ├── 033 - searchInRotatedSortedArray.cpp │ ├── 036 - validSudoku.cpp │ ├── 041 - firstMissingPositive.cpp │ ├── 045 - jumpGameII.cpp │ ├── 049 - groupAnagrams.cpp │ ├── 054 - spiralMatrix.cpp │ ├── 055 - jumpGame.cpp │ ├── 056 - mergeIntervals.cpp │ ├── 057 - insertInterval.cpp │ ├── 066 - plusOne.cpp │ ├── 070 - climbingStairs.cpp │ ├── 074 - searchA2DMatrix.cpp │ ├── 075 - sortColors.cpp │ ├── 078 - subsets.cpp │ ├── 086 - partitionList.cpp │ ├── 098 - validateBinarySearchTree.cpp │ ├── 100 - sameTree.cpp │ ├── 101 - symmetricTree.cpp │ ├── 102 - binaryTreeLevelOrderTraversal.cpp │ ├── 104 - maximumDepthOfBinaryTree.cpp │ ├── 111 - minimumDepthOfBinaryTree.cpp │ ├── 112 - pathSum.cpp │ ├── 113 - pathSumII.cpp │ ├── 114 - flattenBinaryTreeToLinkedList.cpp │ ├── 121 - bestTimeToBuyAndSellStock.cpp │ ├── 122 - bestTimeToBuyAndSellStockII.cpp │ ├── 124 - binaryTreeMaximumPathSum.cpp │ ├── 125 - validPalindrome.cpp │ ├── 129 - sumRootToLeafNumbers.cpp │ ├── 136 - singleNumber.cpp │ ├── 137 - singleNumberII.cpp │ ├── 141 - linkedListCycle.cpp │ ├── 142 - linkedListCycleII.cpp │ ├── 143 - reorderList.cpp │ ├── 144 - binaryTreePreorderTraversal.cpp │ ├── 145 - binaryTreePostOrderTraversal.cpp │ ├── 153 - findMinimumInRotatedSortedArray.cpp │ ├── 155 - minStack.cpp │ ├── 162 - findPeakElement.cpp │ ├── 169 - majorityElement.cpp │ ├── 172 - factorialTrailingZeroes.cpp │ ├── 191 - numberOfOneBits.cpp │ ├── 198 - houseRobber.cpp │ ├── 200 - numberOfIslands.cpp │ ├── 202 - happyNumber.cpp │ ├── 206 - reverseLinkedList.cpp │ ├── 215 - kthLargestElementInAnArray.cpp │ ├── 217 - containsDuplicate.cpp │ ├── 226 - invertBinaryTree.cpp │ ├── 234 - palindromeLinkedList.cpp │ ├── 235 - lowestCommonAncestorOfABinarySearchTree.cpp │ ├── 236 - lowestCommonAncestorOfABinaryTree.cpp │ ├── 237 - deleteNodeInALinkedList.cpp │ ├── 238 - productOfArrayExceptSelf.cpp │ ├── 242 - validAnagram.cpp │ ├── 257 - binaryTreePaths.cpp │ ├── 258 - addDigits.cpp │ ├── 278 - firstBadVersion.cpp │ ├── 292 - nimGame.cpp │ ├── 293 - flipGame.cpp │ ├── 300 - longestIncreasingSubsequence.cpp │ ├── 328 - oddEvenLinkedList.cpp │ ├── 344 - reverseString.cpp │ ├── 412 - fizzBuzz.cpp │ ├── 419 - battleshipsInABoard.cpp │ ├── 461 - hammingDistancecpp.cpp │ ├── 540 - singleElementInASortedArray.cpp │ ├── 617 - mergeTwoBinaryTrees.cpp │ └── 657 - judgeRouteCircle.cpp │ ├── SolutionNavigator.cpp │ ├── SolutionNavigator.vcxproj │ └── SolutionNavigator.vcxproj.filters └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # Benchmark Results 46 | BenchmarkDotNet.Artifacts/ 47 | 48 | # .NET Core 49 | project.lock.json 50 | project.fragment.lock.json 51 | artifacts/ 52 | **/Properties/launchSettings.json 53 | 54 | *_i.c 55 | *_p.c 56 | *_i.h 57 | *.ilk 58 | *.meta 59 | *.obj 60 | *.pch 61 | *.pdb 62 | *.pgc 63 | *.pgd 64 | *.rsp 65 | *.sbr 66 | *.tlb 67 | *.tli 68 | *.tlh 69 | *.tmp 70 | *.tmp_proj 71 | *.log 72 | *.vspscc 73 | *.vssscc 74 | .builds 75 | *.pidb 76 | *.svclog 77 | *.scc 78 | 79 | # Chutzpah Test files 80 | _Chutzpah* 81 | 82 | # Visual C++ cache files 83 | ipch/ 84 | *.aps 85 | *.ncb 86 | *.opendb 87 | *.opensdf 88 | *.sdf 89 | *.cachefile 90 | *.VC.db 91 | *.VC.VC.opendb 92 | 93 | # Visual Studio profiler 94 | *.psess 95 | *.vsp 96 | *.vspx 97 | *.sap 98 | 99 | # TFS 2012 Local Workspace 100 | $tf/ 101 | 102 | # Guidance Automation Toolkit 103 | *.gpState 104 | 105 | # ReSharper is a .NET coding add-in 106 | _ReSharper*/ 107 | *.[Rr]e[Ss]harper 108 | *.DotSettings.user 109 | 110 | # JustCode is a .NET coding add-in 111 | .JustCode 112 | 113 | # TeamCity is a build add-in 114 | _TeamCity* 115 | 116 | # DotCover is a Code Coverage Tool 117 | *.dotCover 118 | 119 | # Visual Studio code coverage results 120 | *.coverage 121 | *.coveragexml 122 | 123 | # NCrunch 124 | _NCrunch_* 125 | .*crunch*.local.xml 126 | nCrunchTemp_* 127 | 128 | # MightyMoose 129 | *.mm.* 130 | AutoTest.Net/ 131 | 132 | # Web workbench (sass) 133 | .sass-cache/ 134 | 135 | # Installshield output folder 136 | [Ee]xpress/ 137 | 138 | # DocProject is a documentation generator add-in 139 | DocProject/buildhelp/ 140 | DocProject/Help/*.HxT 141 | DocProject/Help/*.HxC 142 | DocProject/Help/*.hhc 143 | DocProject/Help/*.hhk 144 | DocProject/Help/*.hhp 145 | DocProject/Help/Html2 146 | DocProject/Help/html 147 | 148 | # Click-Once directory 149 | publish/ 150 | 151 | # Publish Web Output 152 | *.[Pp]ublish.xml 153 | *.azurePubxml 154 | # Note: Comment the next line if you want to checkin your web deploy settings, 155 | # but database connection strings (with potential passwords) will be unencrypted 156 | *.pubxml 157 | *.publishproj 158 | 159 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 160 | # checkin your Azure Web App publish settings, but sensitive information contained 161 | # in these scripts will be unencrypted 162 | PublishScripts/ 163 | 164 | # NuGet Packages 165 | *.nupkg 166 | # The packages folder can be ignored because of Package Restore 167 | **/packages/* 168 | # except build/, which is used as an MSBuild target. 169 | !**/packages/build/ 170 | # Uncomment if necessary however generally it will be regenerated when needed 171 | #!**/packages/repositories.config 172 | # NuGet v3's project.json files produces more ignorable files 173 | *.nuget.props 174 | *.nuget.targets 175 | 176 | # Microsoft Azure Build Output 177 | csx/ 178 | *.build.csdef 179 | 180 | # Microsoft Azure Emulator 181 | ecf/ 182 | rcf/ 183 | 184 | # Windows Store app package directories and files 185 | AppPackages/ 186 | BundleArtifacts/ 187 | Package.StoreAssociation.xml 188 | _pkginfo.txt 189 | *.appx 190 | 191 | # Visual Studio cache files 192 | # files ending in .cache can be ignored 193 | *.[Cc]ache 194 | # but keep track of directories ending in .cache 195 | !*.[Cc]ache/ 196 | 197 | # Others 198 | ClientBin/ 199 | ~$* 200 | *~ 201 | *.dbmdl 202 | *.dbproj.schemaview 203 | *.jfm 204 | *.pfx 205 | *.publishsettings 206 | orleans.codegen.cs 207 | 208 | # Since there are multiple workflows, uncomment next line to ignore bower_components 209 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 210 | #bower_components/ 211 | 212 | # RIA/Silverlight projects 213 | Generated_Code/ 214 | 215 | # Backup & report files from converting an old project file 216 | # to a newer Visual Studio version. Backup files are not needed, 217 | # because we have git ;-) 218 | _UpgradeReport_Files/ 219 | Backup*/ 220 | UpgradeLog*.XML 221 | UpgradeLog*.htm 222 | 223 | # SQL Server files 224 | *.mdf 225 | *.ldf 226 | *.ndf 227 | 228 | # Business Intelligence projects 229 | *.rdl.data 230 | *.bim.layout 231 | *.bim_*.settings 232 | 233 | # Microsoft Fakes 234 | FakesAssemblies/ 235 | 236 | # GhostDoc plugin setting file 237 | *.GhostDoc.xml 238 | 239 | # Node.js Tools for Visual Studio 240 | .ntvs_analysis.dat 241 | node_modules/ 242 | 243 | # Typescript v1 declaration files 244 | typings/ 245 | 246 | # Visual Studio 6 build log 247 | *.plg 248 | 249 | # Visual Studio 6 workspace options file 250 | *.opt 251 | 252 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 253 | *.vbw 254 | 255 | # Visual Studio LightSwitch build output 256 | **/*.HTMLClient/GeneratedArtifacts 257 | **/*.DesktopClient/GeneratedArtifacts 258 | **/*.DesktopClient/ModelManifest.xml 259 | **/*.Server/GeneratedArtifacts 260 | **/*.Server/ModelManifest.xml 261 | _Pvt_Extensions 262 | 263 | # Paket dependency manager 264 | .paket/paket.exe 265 | paket-files/ 266 | 267 | # FAKE - F# Make 268 | .fake/ 269 | 270 | # JetBrains Rider 271 | .idea/ 272 | *.sln.iml 273 | 274 | # CodeRush 275 | .cr/ 276 | 277 | # Python Tools for Visual Studio (PTVS) 278 | __pycache__/ 279 | *.pyc 280 | 281 | # Cake - Uncomment if you are using it 282 | # tools/** 283 | # !tools/packages.config 284 | 285 | # Tabs Studio 286 | *.tss 287 | 288 | # Telerik's JustMock configuration file 289 | *.jmconfig 290 | 291 | # BizTalk build output 292 | *.btp.cs 293 | *.btm.cs 294 | *.odx.cs 295 | *.xsd.cs -------------------------------------------------------------------------------- /AddingNewSolutions.txt: -------------------------------------------------------------------------------- 1 | Untabify 2 | 3 | Problem statement disclaimer 4 | Solution 5 | Be Aware 6 | Test Cases -------------------------------------------------------------------------------- /LeetcodeQuestions/LeetcodeQuestions.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29306.81 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SolutionNavigator", "SolutionNavigator\SolutionNavigator.vcxproj", "{B18D614E-43EF-4FB5-AD23-17CB8799C0DB}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {B18D614E-43EF-4FB5-AD23-17CB8799C0DB}.Debug|x64.ActiveCfg = Debug|x64 17 | {B18D614E-43EF-4FB5-AD23-17CB8799C0DB}.Debug|x64.Build.0 = Debug|x64 18 | {B18D614E-43EF-4FB5-AD23-17CB8799C0DB}.Debug|x86.ActiveCfg = Debug|Win32 19 | {B18D614E-43EF-4FB5-AD23-17CB8799C0DB}.Debug|x86.Build.0 = Debug|Win32 20 | {B18D614E-43EF-4FB5-AD23-17CB8799C0DB}.Release|x64.ActiveCfg = Release|x64 21 | {B18D614E-43EF-4FB5-AD23-17CB8799C0DB}.Release|x64.Build.0 = Release|x64 22 | {B18D614E-43EF-4FB5-AD23-17CB8799C0DB}.Release|x86.ActiveCfg = Release|Win32 23 | {B18D614E-43EF-4FB5-AD23-17CB8799C0DB}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {7B65D341-F0E6-4300-AF12-BDC6E1F1ED01} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/001 - twoSum.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET001_H 2 | #define LEET001_H 3 | 4 | #include "config.h" 5 | 6 | class Solution001 7 | { 8 | public: 9 | std::vector twoSum(std::vector& nums, int target); 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/002 - addTwoNumbers.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET002_H 2 | #define LEET002_H 3 | 4 | #include "config.h" 5 | 6 | struct ListNode 7 | { 8 | int val; 9 | ListNode *next; 10 | ListNode(int x) : val(x), next(nullptr) {} 11 | }; 12 | 13 | class Solution002 14 | { 15 | public: 16 | ListNode* addTwoNumbers(ListNode* l1, ListNode* l2); 17 | }; 18 | 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/003 - longestSubstringWithoutRepeatingCharacters.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET003_H 2 | #define LEET003_H 3 | 4 | #include "config.h" 5 | 6 | class Solution003 7 | { 8 | public: 9 | int lengthOfLongestSubstring(std::string s); 10 | }; 11 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/014 - longestCommonPrefix.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET014_H 2 | #define LEET014_H 3 | 4 | #include "config.h" 5 | 6 | class Solution014 7 | { 8 | public: 9 | std::string longestCommonPrefix(std::vector& strs); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/017 - letterCombinationsOfAPhoneNumber.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET017_H 2 | #define LEET017_H 3 | 4 | #include "config.h" 5 | 6 | class Solution017 7 | { 8 | public: 9 | std::vector letterCombinations(std::string digits); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/019 - removeNthNodeFromEndOfList.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET019_H 2 | #define LEET019_H 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | 13 | struct ListNode 14 | { 15 | int val; 16 | ListNode *next; 17 | ListNode(int x) : val(x), next(nullptr) {} 18 | }; 19 | 20 | class Solution019 21 | { 22 | public: 23 | ListNode* removeNthFromEnd(ListNode* head, int n); 24 | }; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/020 - validParentheses.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET020_H 2 | #define LEET020_H 3 | 4 | #include "config.h" 5 | 6 | class Solution020 7 | { 8 | public: 9 | bool isValid(std::string s); 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/021 - mergeTwoSortedLists.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET021_H 2 | #define LEET021_H 3 | 4 | struct ListNode 5 | { 6 | int val; 7 | ListNode *next; 8 | ListNode(int x) : val(x), next(nullptr) {} 9 | }; 10 | 11 | class Solution021 12 | { 13 | public: 14 | ListNode* mergeTwoLists(ListNode* l1, ListNode* l2); 15 | }; 16 | #endif 17 | 18 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/022 - generateParentheses.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET022_H 2 | #define LEET022_H 3 | 4 | #include "config.h" 5 | 6 | class Solution022 7 | { 8 | public: 9 | std::vector generateParenthesis(int n); 10 | }; 11 | 12 | #endif 13 | 14 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/023 - mergeKSortedLists.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET023_H 2 | #define LEET023_H 3 | 4 | #include "config.h" 5 | 6 | struct ListNode 7 | { 8 | int val; 9 | ListNode *next; 10 | ListNode(int x) : val(x), next(nullptr) {} 11 | }; 12 | 13 | struct LessThanByVal 14 | { 15 | bool operator()(ListNode* &a, ListNode* &b) 16 | { 17 | return (a->val > b->val); 18 | } 19 | }; 20 | 21 | class Solution023 22 | { 23 | public: 24 | ListNode* mergeKLists(std::vector& lists); 25 | }; 26 | 27 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/028 - implementStrstr.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET028_H 2 | #define LEET028_H 3 | 4 | #include "config.h" 5 | class Solution028 6 | { 7 | public: 8 | int strStr(std::string haystack, std::string needle); 9 | }; 10 | #endif 11 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/033 - searchInRotatedSortedArray.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET033_H 2 | #define LEET033_H 3 | 4 | #include "config.h" 5 | 6 | class Solution033 7 | { 8 | public: 9 | int search(std::vector& nums, int target); 10 | }; 11 | 12 | #endif 13 | 14 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/036 - validSudoku.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET036_H 2 | #define LEET036_H 3 | 4 | #include "config.h" 5 | 6 | class Solution036 7 | { 8 | public: 9 | bool isValidSudoku(std::vector>& board); 10 | }; 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/041 - firstMissingPositive.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET041_H 2 | #define LEET041_H 3 | 4 | #include "config.h" 5 | 6 | class Solution041 7 | { 8 | public: 9 | int firstMissingPositive(std::vector& nums); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/045 - jumpGameII.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET045_H 2 | #define LEET045_H 3 | 4 | #include "config.h" 5 | 6 | class Solution045 7 | { 8 | public: 9 | int jump(std::vector& nums); 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/049 - groupAnagrams.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET049_H 2 | #define LEET049_H 3 | 4 | #include "config.h" 5 | 6 | class Solution049 7 | { 8 | public: 9 | std::vector> groupAnagrams(std::vector& strs); 10 | std::string stringSort(std::string& s); 11 | }; 12 | #endif 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/054 - spiralMatrix.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET054_H 2 | #define LEET054_H 3 | 4 | #include "config.h" 5 | class Solution054 6 | { 7 | public: 8 | std::vector spiralOrder(std::vector>& matrix); 9 | }; 10 | #endif 11 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/055 - jumpGame.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET055_H 2 | #define LEET055_H 3 | 4 | #include "config.h" 5 | 6 | class Solution055 7 | { 8 | bool canJump(std::vector& nums); 9 | }; 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/056 - mergeIntervals.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET056_H 2 | #define LEET056_H 3 | 4 | #include "config.h" 5 | 6 | struct Interval 7 | { 8 | int start; 9 | int end; 10 | Interval() : start(0), end(0) {} 11 | Interval(int s, int e) : start(s), end(e) {} 12 | }; 13 | 14 | class Solution056 15 | { 16 | public: 17 | std::vector merge(std::vector& intervals); 18 | }; 19 | #endif 20 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/057 - insertInterval.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET057_H 2 | #define LEET057_H 3 | 4 | #include "config.h" 5 | 6 | struct Interval 7 | { 8 | int start; 9 | int end; 10 | Interval() : start(0), end(0) {} 11 | Interval(int s, int e) : start(s), end(e) {} 12 | }; 13 | 14 | class Solution057 15 | { 16 | public: 17 | std::vector insert(std::vector& intervals, Interval newInterval); 18 | }; 19 | #endif 20 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/066 - plusOne.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET066_H 2 | #define LEET066_H 3 | 4 | #include "config.h" 5 | 6 | class Solution066 7 | { 8 | public: 9 | std::vector plusOne(std::vector& digits); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/070 - climbingStairs.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET070_H 2 | #define LEET070_H 3 | 4 | class Solution070 5 | { 6 | public: 7 | int climbStairs(int n); 8 | }; 9 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/074 - searchA2DMatrix.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET074_H 2 | #define LEET074_H 3 | 4 | #include "config.h" 5 | 6 | class Solution074 7 | { 8 | public: 9 | bool searchMatrix(std::vector>& matrix, int target); 10 | }; 11 | #endif 12 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/075 - sortColors.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET075_H 2 | #define LEET075_H 3 | 4 | #include "config.h" 5 | 6 | class Solution075 7 | { 8 | public: 9 | void sortColors(std::vector& nums); 10 | }; 11 | #endif 12 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/078 - subsets.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET078_H 2 | #define LEET078_H 3 | 4 | #include "config.h" 5 | 6 | class Solution078 7 | { 8 | public: 9 | std::vector> subsets(std::vector& nums); 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/086 - partitionList.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET086_H 2 | #define LEET086_H 3 | 4 | 5 | struct ListNode 6 | { 7 | int val; 8 | ListNode *next; 9 | ListNode(int x) : val(x), next(nullptr) {} 10 | }; 11 | 12 | class Solution086 13 | { 14 | public: 15 | ListNode* partition(ListNode* head, int x); 16 | }; 17 | #endif 18 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/098 - validateBinarySearchTree.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET098_H 2 | #define LEET098_H 3 | 4 | struct TreeNode 5 | { 6 | int val; 7 | TreeNode* left; 8 | TreeNode* right; 9 | TreeNode (int x) : val(x), left(nullptr), right(nullptr) {} 10 | }; 11 | 12 | class Solution098 13 | { 14 | public: 15 | bool isValidBST(TreeNode* root); 16 | bool validate(TreeNode* root, TreeNode* &prev); 17 | }; 18 | #endif 19 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/100 - sameTree.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET100_H 2 | #define LEET100_H 3 | 4 | struct TreeNode 5 | { 6 | int val; 7 | TreeNode *left; 8 | TreeNode *right; 9 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 10 | }; 11 | 12 | class Solution100 13 | { 14 | public: 15 | bool isSameTree(TreeNode* p, TreeNode* q); 16 | }; 17 | #endif 18 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/101 - symmetricTree.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET101_H 2 | #define LEET101_H 3 | 4 | struct TreeNode 5 | { 6 | int val; 7 | TreeNode *left; 8 | TreeNode *right; 9 | TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 10 | }; 11 | 12 | class Solution101 13 | { 14 | public: 15 | bool isSymmetric(TreeNode* root); 16 | bool isSymmetricHelper(TreeNode* r1, TreeNode* r2); 17 | }; 18 | #endif 19 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/102 - binaryTreeLevelOrderTraversal.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET102_H 2 | #define LEET102_H 3 | 4 | 5 | 6 | #include "config.h" 7 | 8 | struct TreeNode 9 | { 10 | int val; 11 | TreeNode *left; 12 | TreeNode *right; 13 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 14 | }; 15 | 16 | class Solution102 17 | { 18 | public: 19 | std::vector> levelOrder(TreeNode* root); 20 | }; 21 | #endif 22 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/104 - maximumDepthOfBinaryTree.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET104_H 2 | #define LEET104_H 3 | 4 | 5 | struct TreeNode 6 | { 7 | int val; 8 | TreeNode *left; 9 | TreeNode *right; 10 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | }; 12 | 13 | class Solution104 14 | { 15 | public: 16 | int maxDepth(TreeNode* root); 17 | }; 18 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/111 - minimumDepthOfBinaryTree.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET111_H 2 | #define LEET111_H 3 | 4 | struct TreeNode 5 | { 6 | int val; 7 | TreeNode *left; 8 | TreeNode *right; 9 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 10 | }; 11 | 12 | class Solution111 13 | { 14 | public: 15 | int minDepth(TreeNode* root); 16 | int minDepthHelper(TreeNode* root); 17 | }; 18 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/112 - pathSum.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET112_H 2 | #define LEET112_H 3 | 4 | 5 | 6 | struct TreeNode 7 | { 8 | int val; 9 | TreeNode *left; 10 | TreeNode *right; 11 | TreeNode (int x) : val(x), left(nullptr), right(nullptr) {} 12 | }; 13 | 14 | class Solution112 15 | { 16 | public: 17 | bool hasPathSum(TreeNode* root, int sum); 18 | bool hasPathSumHelper(TreeNode* root, int sum, int current); 19 | }; 20 | #endif 21 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/113 - pathSumII.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET113_H 2 | #define LEET113_H 3 | 4 | #include "config.h" 5 | /** 6 | * Definition for a binary tree node. 7 | * struct TreeNode { 8 | * int val; 9 | * TreeNode *left; 10 | * TreeNode *right; 11 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 12 | * }; 13 | */ 14 | 15 | struct TreeNode 16 | { 17 | int val; 18 | TreeNode *left; 19 | TreeNode *right; 20 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 21 | }; 22 | 23 | class Solution113 24 | { 25 | public: 26 | std::vector> pathSum(TreeNode* root, int sum); 27 | void pathSumHelper(TreeNode* root, int sum, std::vector& path, std::vector>& result); 28 | }; 29 | 30 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/114 - flattenBinaryTreeToLinkedList.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET114_H 2 | #define LEET114_H 3 | 4 | 5 | struct TreeNode 6 | { 7 | int val; 8 | TreeNode *left; 9 | TreeNode *right; 10 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | }; 12 | 13 | class Solution114 14 | { 15 | public: 16 | void flatten(TreeNode* root); 17 | }; 18 | #endif 19 | 20 | 21 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/121 - bestTimeToBuyAndSellStock.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET121_H 2 | #define LEET121_H 3 | 4 | #include "config.h" 5 | 6 | class Solution121 7 | { 8 | public: 9 | int maxProfit(std::vector& prices); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/122 - bestTimeToBuyAndSellStockII.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET122_H 2 | #define LEET122_H 3 | 4 | #include "config.h" 5 | 6 | class Solution122 7 | { 8 | public: 9 | int maxProfit(std::vector& prices); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/124 - binaryTreeMaximumPathSum.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET124_H 2 | #define LEET124_H 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | 14 | struct TreeNode 15 | { 16 | int val; 17 | TreeNode *left; 18 | TreeNode *right; 19 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 20 | }; 21 | 22 | class Solution124 23 | { 24 | public: 25 | int maxPathSum(TreeNode* root); 26 | int maxPathSumHelper(TreeNode* root, int& result); 27 | }; 28 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/125 - validPalindrome.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET125_H 2 | #define LEET125_H 3 | 4 | #include "config.h" 5 | 6 | class Solution125 7 | { 8 | public: 9 | bool isPalindrome(std::string s); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/129 - sumRootToLeafNumbers.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET129_H 2 | #define LEET129_H 3 | 4 | 5 | struct TreeNode 6 | { 7 | int val; 8 | TreeNode* left; 9 | TreeNode* right; 10 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | }; 12 | 13 | class Solution129 14 | { 15 | public: 16 | int sumNumbers(TreeNode* root); 17 | 18 | int sumNumbersHelper(TreeNode* root, int path); 19 | }; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/136 - singleNumber.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET136_H 2 | #define LEET136_H 3 | 4 | #include "config.h" 5 | 6 | class Solution136 7 | { 8 | public: 9 | int singleNumber(std::vector& nums); 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/137 - singleNumberII.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET137_H 2 | #define LEET137_H 3 | 4 | #include "config.h" 5 | 6 | class Solution137 7 | { 8 | public: 9 | int singleNumber(std::vector& nums); 10 | }; 11 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/141 - linkedListCycle.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET141_H 2 | #define LEET141_H 3 | 4 | struct ListNode 5 | { 6 | int val; 7 | ListNode *next; 8 | ListNode(int x) : val(x), next(nullptr) {} 9 | }; 10 | 11 | class Solution141 12 | { 13 | public: 14 | bool hasCycle(ListNode *head); 15 | }; 16 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/142 - linkedListCycleII.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET142_H 2 | #define LEET142_H 3 | 4 | struct ListNode 5 | { 6 | int val; 7 | ListNode *next; 8 | ListNode(int x) : val(x), next(nullptr) {} 9 | }; 10 | 11 | class Solution142 12 | { 13 | public: 14 | ListNode* detectCycle(ListNode *head); 15 | }; 16 | #endif 17 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/143 - reorderList.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET143_H 2 | #define LEET143_H 3 | 4 | 5 | struct ListNode 6 | { 7 | int val; 8 | ListNode *next; 9 | ListNode(int x) : val(x), next(nullptr) {} 10 | }; 11 | 12 | class Solution143 13 | { 14 | public: 15 | void reorderList(ListNode* head); 16 | }; 17 | #endif 18 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/144 - binaryTreePreorderTraversal.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET144_H 2 | #define LEET144_H 3 | 4 | #include "config.h" 5 | 6 | struct TreeNode 7 | { 8 | int val; 9 | TreeNode* left; 10 | TreeNode* right; 11 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | }; 13 | 14 | class Solution144 15 | { 16 | public: 17 | std::vector preorderTraversal(TreeNode* root); 18 | }; 19 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/145 - binaryTreePostorderTraversal.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET145_H 2 | #define LEET145_H 3 | 4 | #include "config.h" 5 | 6 | struct TreeNode 7 | { 8 | int val; 9 | TreeNode *left; 10 | TreeNode *right; 11 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | }; 13 | 14 | class Solution145 15 | { 16 | public: 17 | std::vector postorderTraversal(TreeNode* root); 18 | }; 19 | #endif 20 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/153 - findMinimumInRotatedSortedArray.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET153_H 2 | #define LEET153_H 3 | 4 | #include "config.h" 5 | class Solution153 6 | 7 | { 8 | public: 9 | int findMin(std::vector& nums); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/155 - minStack.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET155_H 2 | #define LEET155_H 3 | 4 | #include "config.h" 5 | 6 | class Solution155 7 | { 8 | public: 9 | /** initialize your data structure here. */ 10 | Solution155() 11 | { 12 | } 13 | 14 | void push(int x); 15 | void pop(); 16 | int top(); 17 | int getMin(); 18 | 19 | private: 20 | std::stack stk; 21 | std::stack mins; 22 | }; 23 | 24 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/162 - findPeakElement.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET162_H 2 | #define LEET162_H 3 | 4 | #include "config.h" 5 | 6 | class Solution162 7 | { 8 | public: 9 | int findPeakElement(std::vector& nums); 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/169 - majorityElement.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET169_H 2 | #define LEET169_H 3 | 4 | #include "config.h" 5 | 6 | class Solution169 7 | { 8 | public: 9 | int majorityElement(std::vector& nums); 10 | }; 11 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/172 - factorialTrailingZeroes.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET172_H 2 | #define LEET172_H 3 | 4 | class Solution172 5 | { 6 | public: 7 | int trailingZeroes(int n); 8 | }; 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/191 - numberOfOneBits.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET191_H 2 | #define LEET191_H 3 | 4 | #include "config.h" 5 | 6 | class Solution191 7 | { 8 | public: 9 | int hammingWeight(uint32_t n); 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/198 - houseRobber.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET198_H 2 | #define LEET198_H 3 | 4 | #include "config.h" 5 | 6 | class Solution198 7 | { 8 | public: 9 | int rob(std::vector& nums); 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/200 - numberOfIslands.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET200_H 2 | #define LEET200_H 3 | 4 | #include "config.h" 5 | 6 | class Solution200 7 | { 8 | public: 9 | int numIslands(std::vector>& grid); 10 | void markByBFS(std::vector>& grid, int x, int y); 11 | }; 12 | #endif 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/202 - happyNumber.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET202_H 2 | #define LEET202_H 3 | 4 | class Solution202 5 | { 6 | public: 7 | bool isHappy(int n); 8 | 9 | int digitSumSquare(int n); 10 | }; 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/206 - reverseLinkedList.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET206_H 2 | #define LEET206_H 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | 13 | struct ListNode 14 | { 15 | int val; 16 | ListNode *next; 17 | ListNode(int x) : val(x), next(nullptr) {} 18 | }; 19 | 20 | class Solution206 21 | { 22 | public: 23 | ListNode* reverseList(ListNode* head); 24 | }; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/215 - kthLargestElementInAnArray.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET215_H 2 | #define LEET215_H 3 | 4 | #include "config.h" 5 | 6 | class Solution215 7 | { 8 | public: 9 | int findKthLargest(std::vector& nums, int k); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/217 - containsDuplicate.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET217_H 2 | #define LEET217_H 3 | 4 | #include "config.h" 5 | 6 | class Solution217 7 | { 8 | public: 9 | bool containsDuplicate(std::vector& nums); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/226 - invertBinaryTree.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET226_H 2 | #define LEET226_H 3 | 4 | #include "config.h" 5 | 6 | struct TreeNode 7 | { 8 | int val; 9 | TreeNode *left; 10 | TreeNode *right; 11 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 12 | }; 13 | 14 | class Solution226 15 | { 16 | public: 17 | TreeNode* invertTree(TreeNode* root); 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/234 - palindromeLinkedList.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET234_H 2 | #define LEET234_H 3 | 4 | struct ListNode 5 | { 6 | int val; 7 | ListNode *next; 8 | ListNode(int x) : val(x), next(nullptr) {} 9 | }; 10 | 11 | class Solution234 12 | { 13 | public: 14 | bool isPalindrome(ListNode* head); 15 | ListNode* reverseList(ListNode* head); 16 | }; 17 | #endif 18 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/235 - lowestCommonAncestorOfABinarySearchTree.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET235_H 2 | #define LEET235_H 3 | 4 | /** 5 | * Definition for a binary tree node. 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | 14 | struct TreeNode 15 | { 16 | int val; 17 | TreeNode *left; 18 | TreeNode *right; 19 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 20 | }; 21 | 22 | class Solution235 23 | { 24 | public: 25 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q); 26 | }; 27 | #endif 28 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/236 - lowestCommonAncestorOfABinaryTree.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET236_H 2 | #define LEET236_H 3 | 4 | struct TreeNode 5 | { 6 | int val; 7 | TreeNode *left; 8 | TreeNode *right; 9 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 10 | }; 11 | 12 | class Solution236 13 | { 14 | public: 15 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q); 16 | }; 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/237 - deleteNodeInALinkedList.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET237_H 2 | #define LEET237_H 3 | 4 | struct ListNode 5 | { 6 | int val; 7 | ListNode *next; 8 | ListNode(int x) : val(x), next(nullptr) {} 9 | }; 10 | 11 | class Solution237 12 | { 13 | public: 14 | void deleteNode(ListNode* node); 15 | }; 16 | #endif 17 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/238 - productOfArrayExceptSelf.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET238_H 2 | #define LEET238_H 3 | 4 | #include "config.h" 5 | 6 | class Solution238 7 | { 8 | public: 9 | std::vector productExceptSelf(std::vector& nums); 10 | }; 11 | 12 | #endif 13 | 14 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/242 - validAnagram.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET242_H 2 | #define LEET242_H 3 | 4 | #include "config.h" 5 | 6 | class Solution242 7 | { 8 | public: 9 | bool isAnagram(std::string s, std::string t); 10 | }; 11 | #endif 12 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/257 - binaryTreePaths.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET257_H 2 | #define LEET257_H 3 | 4 | #include "config.h" 5 | 6 | struct TreeNode 7 | { 8 | int val; 9 | TreeNode *left; 10 | TreeNode *right; 11 | TreeNode (int x) : val(x), left(nullptr), right(nullptr) {} 12 | }; 13 | 14 | class Solution257 15 | { 16 | public: 17 | std::vector binaryTreePaths(TreeNode* root); 18 | void binaryTreePathsHelper(TreeNode* root, std::string curPath, std::vector& result); 19 | }; 20 | #endif 21 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/258 - addDigits.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET258_H 2 | #define LEET258_H 3 | 4 | #include "config.h" 5 | 6 | class Solution258 7 | { 8 | public: 9 | int addDigits(int num); 10 | }; 11 | #endif 12 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/278 - firstBadVersion.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET278_H 2 | #define LEET278_H 3 | 4 | 5 | class Solution278 6 | { 7 | public: 8 | int firstBadVersion(int n); 9 | private: 10 | bool isBadVersion(int n); 11 | }; 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/292 - nimGame.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET292_H 2 | #define LEET292_H 3 | 4 | #include "config.h" 5 | 6 | class Solution292 7 | { 8 | public: 9 | bool canWinNim(int n); 10 | }; 11 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/293 - flipGame.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET293_H 2 | #define LEET293_H 3 | 4 | #include "config.h" 5 | 6 | class Solution293 7 | { 8 | public: 9 | std::vector generatePossibleNextMoves(std::string s); 10 | }; 11 | #endif 12 | 13 | 14 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/300 - longestIncreasingSubsequence.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET300_H 2 | #define LEET300_H 3 | 4 | #include "config.h" 5 | 6 | class Solution300 7 | { 8 | public: 9 | int lengthOfLIS(std::vector& nums); 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/328 - oddEvenLinkedList.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET328_H 2 | #define LEET328_H 3 | 4 | struct ListNode 5 | { 6 | int val; 7 | ListNode *next; 8 | ListNode(int x) : val(x), next(nullptr) { } 9 | }; 10 | class Solution328 11 | { 12 | public: 13 | ListNode* oddEvenList(ListNode* head); 14 | }; 15 | #endif 16 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/344 - reverseString.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET344_H 2 | #define LEET344_H 3 | 4 | #include "config.h" 5 | 6 | class Solution344 7 | { 8 | public: 9 | std::string reverseString(std::string s); 10 | }; 11 | #endif 12 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/412 - fizzBuzz.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET412_H 2 | #define LEET412_H 3 | 4 | #include "config.h" 5 | 6 | class Solution412 7 | { 8 | public: 9 | std::vector fizzBuzz(int n); 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/419 - battleshipsInABoard.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET419_H 2 | #define LEET419_H 3 | 4 | #include "config.h" 5 | 6 | class Solution419 7 | { 8 | public: 9 | int countBattleships(std::vector>& board); 10 | }; 11 | #endif 12 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/461 - hammingDistance.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET461_H 2 | #define LEET461_H 3 | 4 | class Solution461 5 | { 6 | public: 7 | int hammingDistance(int x, int y); 8 | }; 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/540 - singleElementInASortedArray.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET540_H 2 | #define LEET540_H 3 | 4 | #include "config.h" 5 | 6 | class Solution540 7 | { 8 | public: 9 | int singleNonDuplicate(std::vector& nums); 10 | }; 11 | #endif 12 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/617 - mergeTwoBinaryTrees.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET617_H 2 | #define LEET617_H 3 | 4 | struct TreeNode 5 | { 6 | int val; 7 | TreeNode *left; 8 | TreeNode *right; 9 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 10 | }; 11 | 12 | class Solution617 13 | { 14 | public: 15 | TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2); 16 | }; 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/657 - judgeRouteCircle.h: -------------------------------------------------------------------------------- 1 | #ifndef LEET657_H 2 | #define LEET657_H 3 | 4 | #include "config.h" 5 | 6 | class Solution657 7 | { 8 | public: 9 | bool judgeCircle(std::string moves); 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Header Files/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | //Global includes for convenience, remember to avoid namespace poisoning! 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | #endif -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/001 - twoSum.cpp: -------------------------------------------------------------------------------- 1 | #include "001 - twoSum.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to Leetcode's "Two Sum" for the problem statement. 9 | https://leetcode.com/problems/two-sum/description/ 10 | 11 | Solution: 12 | The basic principle is to create a hashMap of ints to ints with a number as a key and its index in the given vector as the value. 13 | 14 | We begin with such a data structure without any items inside. 15 | Iterate through the provided vector 16 | -If the number in the considered spot has its counterpart that sums to the target in the hashmap, return that stored index and the current index as the solution. 17 | -Otherwise, add the current pair to the hashmap and continue iterating. 18 | Proceed until completed. 19 | 20 | Let N be the size of the input array 21 | Time Complexity: O(N^2), one iteration of the for loop, each insertion worst case O(N). However, in practice this will be much closer to O(1) 22 | Space Complexity: O(N), assuming a solution pair exists then worst case N - 1 pair entries will be added. 23 | */ 24 | vector Solution001::twoSum(vector& nums, int target) 25 | { 26 | vector result; 27 | unordered_map hashMap; 28 | 29 | for (int i = 0; i < nums.size(); i++) 30 | { 31 | if (hashMap.count(target - nums[i]) != 0) 32 | { 33 | result.push_back(hashMap.find(target - nums[i])->second); 34 | result.push_back(i); 35 | break; 36 | } 37 | 38 | hashMap.insert(pair(nums[i], i)); 39 | } 40 | 41 | return result; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/002 - addTwoNumbers.cpp: -------------------------------------------------------------------------------- 1 | #include "002 - addTwoNumbers.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Medium 6 | Please refer to Leetcode's "2. Add Two Numbers" for the problem statement. 7 | https://leetcode.com/problems/add-two-numbers/description/ 8 | 9 | Solution: 10 | It is just a matter of keeping track of where you are at each linked list and performing additions on the digits, propagating a carry along (in case the sum of the digits exceeds 10). 11 | 12 | Let M be length of first linked list, N be the length of second linked list. 13 | Time Complexity: O(max(M, N)), while loop continues so long as one list hasn't been completely iterated through yet. 14 | Space Complexity: O(1), only 1 sentinel node is created per function call. 15 | 16 | Be Aware: 17 | -Make sure to account for the case of different length linked list inputs. 18 | -Remember to push back a ListNode that holds the carry at the end if it exists. 19 | -This code can be written with three while loops, with the first one as "while (l1 != nullptr && l2 != nullptr)". Why might this approach not be ideal? 20 | -having a sentinel node that points to the start of the actual solution is a strategy that in some cases allows you to avoid coding for special nullptr scenarios. 21 | 22 | Tests: 23 | l1: 2 -> 4 -> 3 24 | l2: 5 -> 6 -> 4 25 | 26 | l1: 0 27 | l2: 0 28 | 29 | l1: 0 30 | l2: 1 31 | 32 | l1: 1 33 | l2: 9 -> 9 -> 9 34 | 35 | l1: 3 -> 4 -> 7 36 | l2: 2 -> 5 -> 1 -> 8 37 | */ 38 | 39 | /** 40 | * Definition for singly-linked list. 41 | * struct ListNode { 42 | * int val; 43 | * ListNode *next; 44 | * ListNode(int x) : val(x), next(NULL) {} 45 | * }; 46 | */ 47 | ListNode* Solution002::addTwoNumbers(ListNode* l1, ListNode* l2) 48 | { 49 | ListNode* sentinel = new ListNode(0); 50 | ListNode* iter = sentinel; 51 | int rval, carry = 0; 52 | 53 | while (l1 != nullptr || l2 != nullptr) 54 | { 55 | if (l1 != nullptr && l2 != nullptr) 56 | rval = l1->val + l2->val + carry; 57 | else if (l1 != nullptr) 58 | rval = l1->val + carry; 59 | else 60 | rval = l2->val + carry; 61 | 62 | carry = rval / 10; 63 | rval = rval % 10; 64 | 65 | iter->next = new ListNode(rval); 66 | iter = iter->next; 67 | 68 | if (l1 != nullptr) l1 = l1->next; 69 | if (l2 != nullptr) l2 = l2->next; 70 | } 71 | 72 | if (carry) iter->next = new ListNode(carry); 73 | 74 | return sentinel->next; 75 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/003 - longestSubstringWithoutRepeatingCharacters.cpp: -------------------------------------------------------------------------------- 1 | #include "003 - longestSubstringWithoutRepeatingCharacters.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "3. Longest Substring Without Repeating Characters" for the problem statement. 9 | https://leetcode.com/problems/longest-substring-without-repeating-characters/description/ 10 | 11 | Solution: 12 | You can obviously brute force it by calculating everything, but this will take too much time. 13 | You can apply a dynamic programming paradigm here, and try to find a recurrence. 14 | If we consider adding a character, the longest substring without a repeating character in the first N characters of the input string can be: 15 | 1. The optimal answer from the first N - 1 characters, which DOESN'T include the Nth character. 16 | 2. The answer that DOES include the Nth character. 17 | Sample Recurrence: 18 | OPT(n) -> max(OPT(n - 1), n - indexWithLatestRepeatedCharacter)) 19 | 20 | Let N be the length of the input string 21 | Time Complexity: O(N), assuming constant time library functions, otherwise O(N^2) (find_last_of will take at most O(N) time) 22 | Space Complexity: O(N), vector to keep track of longest substring up to that point. 23 | 24 | Be Aware: 25 | -This solution has room for improvement! The initialization is not quite clean and the library function find_last_of technically can run in O(N), though it generally will be close to constant. 26 | -However, as of 8/2/2017, this solution beats 78% of .cpp submissions on LeetCode, supporting the hypothesis that find_last_of has good average runtime. 27 | -Dynamic programming solutions generally take extra space, but save in time. 28 | -The latest repeated character is not necessarily going to be the Nth character you are considering. ex: ABBA. 29 | 30 | Test Cases: 31 | "" 32 | "A" 33 | "AB" 34 | "abcabcbb" 35 | "pwwkew" 36 | "bbbbbbbbb" 37 | */ 38 | 39 | int lengthOfLongestSubstring(string s) 40 | { 41 | if (s.size() == 1) return 1; 42 | 43 | vector optimals(s.length() + 1, 0); 44 | int potential, repeatIndex = 0; 45 | for(int i = 1; i < s.length(); i++) 46 | { 47 | potential = s.find_last_of(s[i], i - 1) + 1; //New character might move up the index of the last repeat 48 | if(potential != string::npos && potential > repeatIndex) repeatIndex = potential; 49 | optimals[i + 1] = max(optimals[i], i - repeatIndex + 1); 50 | } 51 | 52 | return optimals[s.length()]; 53 | } 54 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/014 - longestCommonPrefix.cpp: -------------------------------------------------------------------------------- 1 | #include "014 - longestCommonPrefix.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "14. Longest Common Prefix" for the problem statement. 9 | https://leetcode.com/problems/longest-common-prefix/description/ 10 | 11 | Solution: 12 | The implemented approach is vertical scanning. That is, we look at every string's first character, then the 2nd, then the 3rd, and so on until we find an index where there is a mismatch. 13 | The benefit of this approach over horizontal scanning is that if there is a very short string at the end of the data set we will end much earlier than with horizontal scanning. 14 | However, in the worst case scenario both have the same complexity. 15 | Time complexity: O(MN), where M is the length of the longest string and N is the number of strings in the data set 16 | Space complexity: O(1), only using a single string for results storage 17 | Be aware: 18 | -There are multiple solutions to this problem, including vertical scanning, horizontal scanning, and divide and conquer 19 | -Vertical scanning's complexity is about as minimal as you can get, however. 20 | Tests: 21 | {"A", "B", "C"} 22 | {"AAA", "AAAA", "AAAB"} 23 | {"A", "AA", "AAA"} 24 | {"Overwatch", "Overcome", "Overdo", "Overpower"} 25 | {"man", "woman"} 26 | */ 27 | 28 | string Solution014::longestCommonPrefix(vector& strs) 29 | { 30 | if (strs.size() == 0) return ""; 31 | string result = ""; 32 | int max_prefix_len = INT_MAX; 33 | for (int i = 0; i < strs.size(); i++) 34 | { 35 | max_prefix_len = min(max_prefix_len, (int)strs[i].length()); 36 | } 37 | 38 | for (int j = 0; j < max_prefix_len; j++) 39 | { 40 | char c = strs[0][j]; 41 | for (int k = 0; k < strs.size(); k++) 42 | { 43 | if (strs[k][j] != c) return result; 44 | } 45 | result += c; 46 | } 47 | 48 | return result; 49 | } 50 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/017 - letterCombinationsOfAPhoneNumber.cpp: -------------------------------------------------------------------------------- 1 | #include "017 - letterCombinationsOfAPhoneNumber.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "17. Letter Combinations of a Phone Number" for the problem statement. 9 | https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/ 10 | Credit to LeetCode user asbear for this solution + explanation, found here: 11 | https://discuss.leetcode.com/topic/17262/iterative-c-solution-in-0ms 12 | 13 | Solution: 14 | Backtracking 15 | Take advantage of the fact that the STL vector swap function is constant in time complexity. 16 | Initialize a vector that represents a mapping of digits to possible letters via index. 17 | For every digit in the input digit string, find the digit index by subtracting the char '0'. 18 | For every possible mapping, append each one to each string in temp. 19 | Swap temp and results, because temp currently represents the combinations up to the jth digit, which is what the j + 1 digit will build upon. Conveniently, this also represents the final result if there are no more digits remaining. 20 | 21 | Let N be the length of the digits string 22 | Time Complexity: TODO 23 | Space Complexity: TODO 24 | 25 | Be Aware: 26 | -Make sure to confirm that your usage of library functions is not overly expensive! 27 | -Don't forget to account for the digits where there are no letter mappings and handle them appropriately 28 | 29 | Tests: 30 | Empty String 31 | 1234567890 32 | 111 33 | 2 34 | 0 35 | 1 36 | 133431 37 | */ 38 | 39 | vector Solution017::letterCombinations(string digits) 40 | { 41 | vector result; 42 | if (digits.size() == 0) return vector(); 43 | const vector digit_mapping = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; 44 | result.push_back(""); 45 | 46 | for (int i = 0; i < digits.size(); i++) 47 | { 48 | vector temp; 49 | int dig_index = digits[i] - '0'; 50 | if (dig_index == 0 || dig_index == 1) continue; 51 | for (int j = 0; j < result.size(); j++) 52 | { 53 | for (int k = 0; k < digit_mapping[dig_index].size(); k++) 54 | { 55 | temp.push_back(result[j] + digit_mapping[dig_index][k]); 56 | } 57 | } 58 | result.swap(temp); 59 | } 60 | 61 | 62 | return result; 63 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/019 - removeNthNodeFromEndOfList.cpp: -------------------------------------------------------------------------------- 1 | #include "019 - removeNthNodeFromEndOfList.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Medium 6 | Please refer to "19. Remove Nth Node From End of List" for the problem statement 7 | https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/ 8 | 9 | Solution: 10 | In order to find the nth node from the end, we have a scout node go ahead by the input distance. 11 | Then we can slide both the scout and another node continue forwards until the scout hits a nullptr, at which we will have found the node to remove. 12 | 13 | Let M be the length of the input linked list. 14 | Time Complexity: O(M), iteration to the end of linked list, then constant time deletion 15 | Space Complexity: O(1), just one sentinel node, three pointers, and an integer 16 | 17 | Be Aware: 18 | -Consider the case where the node to delete must be the first node. 19 | -Note that we haven't actually freed the memory associated with the node that we are removing. 20 | 21 | Tests: 22 | -Linked list of size 1 23 | -Linked list of size > 1 24 | -Linked list of size > 1 with the node to delete to be the first node 25 | */ 26 | 27 | ListNode* Solution019::removeNthFromEnd(ListNode* head, int n) 28 | { 29 | ListNode *sentinel = new ListNode(0); 30 | sentinel->next = head; 31 | ListNode *prev = sentinel; 32 | ListNode *scout = head; 33 | int counter = 0; 34 | 35 | while (counter < n) 36 | { 37 | scout = scout->next; 38 | counter++; 39 | } 40 | 41 | while (scout != nullptr) 42 | { 43 | prev = prev->next; 44 | scout = scout->next; 45 | } 46 | 47 | if (prev == sentinel) return head->next; 48 | if (prev->next != nullptr) prev->next = prev->next->next; 49 | return head; 50 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/020 - validParentheses.cpp: -------------------------------------------------------------------------------- 1 | #include "020 - validParentheses.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Easy 6 | Please refer to "20. Valid Parentheses" for the problem statement. 7 | https://leetcode.com/problems/valid-parentheses/description/ 8 | 9 | Solution: 10 | Every time we encounter an opening character, we know that its closing match must be next. 11 | This requirement makes it attractive to use a stack to resolve the issue. 12 | We push open brackets onto it, and pop close brackets off, returning false if we have no open bracket to pop or if it doesnt match 13 | At the end we check to see if the stack has any remaining open brackets, and if not then we have a valid set! 14 | 15 | Let N be the length of the input string 16 | Time Complexity: O(N) 17 | Space Complexity: O(N), worst case entire string consists of opening parentheses and the final check of stack emptiness is what determines the answer 18 | 19 | Be Aware: 20 | -Is there any way to make this code prettier? If so, does it give a significant boost? 21 | -As with all switch statements, don't forget to include your break statements! 22 | 23 | Tests: 24 | "" 25 | "[]" 26 | "[" 27 | "]" 28 | "({[]})" 29 | "{{([]{}[{()[]}])}}" 30 | */ 31 | using namespace std; 32 | 33 | bool Solution020::isValid(string s) 34 | { 35 | stack parenStack; 36 | for (int i = 0; i < s.length(); i++) 37 | { 38 | switch (s[i]) 39 | { 40 | case '(': 41 | case '[': 42 | case '{': 43 | parenStack.push(s[i]); 44 | break; 45 | case ')': 46 | if (!parenStack.empty() && parenStack.top() == '(') parenStack.pop(); 47 | else return false; 48 | break; 49 | case ']': 50 | if (!parenStack.empty() && parenStack.top() == '[') parenStack.pop(); 51 | else return false; 52 | break; 53 | case '}': 54 | if (!parenStack.empty() && parenStack.top() == '{') parenStack.pop(); 55 | else return false; 56 | } 57 | } 58 | 59 | return parenStack.empty(); 60 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/021 - mergeTwoSortedLists.cpp: -------------------------------------------------------------------------------- 1 | #include "021 - mergeTwoSortedLists.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Easy 6 | Please refer to "21. Merge Two Sorted Lists" for the problem statement. 7 | https://leetcode.com/problems/merge-two-sorted-lists/description/ 8 | 9 | Solution: 10 | Fairly straightforward. So long as there exists a node in either list to merge, select the appropriate node and assign it to a ListNode pointer's next. 11 | 12 | Let N be the total number of nodes, that is the sum of the lengths of l1 and l2 13 | Time Complexity: O(N), each node is visited once when merging 14 | Space Complexity: O(1), just one sentinel node per function call, and a pointer 15 | 16 | Be Aware: 17 | -Uses the sentinel node strategy to eliminate need for some edge cases. 18 | -Assumes sorting in increasing order. 19 | 20 | Tests: 21 | l1: [] 22 | l2: [] 23 | 24 | l1: [1] 25 | l2: [] 26 | 27 | l1: [1,2,3,4,5] 28 | l2: [1,3,5,7,9] 29 | 30 | l1: [1,3,5,7,9] 31 | l2: [2,4,6,8] 32 | */ 33 | ListNode* Solution021::mergeTwoLists(ListNode* l1, ListNode* l2) 34 | { 35 | ListNode *sentinel = new ListNode(0); 36 | ListNode *temp = sentinel; 37 | 38 | while (l1 != nullptr || l2 != nullptr) 39 | { 40 | if (l1 != nullptr && l2 != nullptr) 41 | { 42 | if (l1->val < l2->val) 43 | { 44 | temp->next = l1; 45 | l1 = l1->next; 46 | } 47 | else 48 | { 49 | temp->next = l2; 50 | l2 = l2->next; 51 | } 52 | } 53 | else if (l1 != nullptr) 54 | { 55 | temp->next = l1; 56 | l1 = l1->next; 57 | } 58 | else 59 | { 60 | temp->next = l2; 61 | l2 = l2->next; 62 | } 63 | 64 | temp = temp->next; 65 | } 66 | 67 | return sentinel->next; 68 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/022 - generateParentheses.cpp: -------------------------------------------------------------------------------- 1 | #include "022 - generateParentheses.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "22. Generate Parentheses" for the problem statement. 9 | https://leetcode.com/problems/generate-parentheses/description/ 10 | 11 | Solution: 12 | This represents a good example of a backtracking problem, mixed with knowledge of STL functions and data structures. 13 | 14 | For a given length n, we realize that we just need all the different ways to add one pair of parentheses to each of the results produced for n - 1. 15 | Thus, it makes sense to attempt an approach where we start with just the single pair of parentheses and build upwards. 16 | However, while we build up, we want to be sure that we aren't considering duplicate cases. An STL data structure that doesn't keep duplicates is the set. 17 | 18 | Finally, we also keep in mind that if for iteration i we produce result_i, then for the next iteration we should produce result_i+1 based off result_i. 19 | How do we actually achieve this in code? We can use the STL swap function, which operates in constant time, to switch our running result with a temporary vector that stores the results for each iteration. 20 | 21 | Thus, we have 3 nested loops: 22 | -The first loop tells us what n to stop at 23 | -The second loop is a loop through the set of all parentheses combinations we have generated so far 24 | -The third loop is a loop through the length of each parentheses combo to try to insert "()". 25 | 26 | Note that if left unchecked, this approach would produce tons of duplicates. Hence why the usage of a set is so important here! 27 | 28 | Let N be the integer passed into the function call. 29 | Time Complexity: Very big, depndendent on the number of actual parentheses combinations that can be produced. 30 | Note that logically, we would be minimally constrained by having to produce every combination. 31 | Space Complexity: O(N) for the temporary vector 32 | 33 | Be Aware: 34 | -Make sure you are tracking what temp and result are storing at any given time. Don't mistime your swaps! 35 | -For those overwhelmed by the sheer number of possibilities, try considering a brute force way of knowing for sure you have considered every possibility. 36 | 37 | Tests: 38 | 0 39 | 3 40 | 12 41 | 25 42 | */ 43 | 44 | vector Solution022::generateParenthesis(int n) 45 | { 46 | if (n <= 0) return vector(); 47 | 48 | set parens; 49 | parens.insert("()"); 50 | for (int i = 2; i <= n; i++) 51 | { 52 | set temp; 53 | for (set::iterator j = parens.begin(); j != parens.end(); j++) 54 | { 55 | for (int k = 0; k < (*j).size(); k++) 56 | { 57 | string new_item = *j; 58 | new_item.insert(k, "()"); 59 | temp.insert(new_item); 60 | } 61 | } 62 | parens.swap(temp); 63 | } 64 | 65 | return vector(parens.begin(), parens.end()); 66 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/023 - mergeKSortedLists.cpp: -------------------------------------------------------------------------------- 1 | #include "023 - mergeKSortedLists.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Hard 8 | Please refer to "23. Merge k Sorted Lists" for the problem statement. 9 | https://leetcode.com/problems/merge-k-sorted-lists/description/ 10 | 11 | Solution: 12 | Let k be the number of sorted lists we have. 13 | Let N be the total number of elements we have across all lists. 14 | 15 | Our solution is to use a minheap that keeps pointers to non-nullptr nodes sorted in ascending order by the value stored within said nodes. 16 | Thus, in order to access the next smallest item when building our merged list, it will only cost O(1) time to access, and then O(logk) to handle adding the next node and removing the one just considered. 17 | Because we are building a merged list, we will need to visit each node one time, so each node will be a part of this minheap at some point (it needs to be the next item in order to be merged in). 18 | Thus... 19 | 20 | Time Complexity: O(NlogK) 21 | Space Complexity: O(k) 22 | 23 | Be Aware: 24 | -There are a multitude of ways to solve this problem. For example, one can scan the front of each linked list to find the smallest element to add. This removes the need for a heap. 25 | However, it's time complexity becomes O(Nk) 26 | 27 | Tests: 28 | Empty Set 29 | 5 lists each with 1 item 30 | 5 lists, all but one with no items 31 | [1,4,7,10], [2, 5, 8, 11, 13], [3, 6, 9, 12, 14, 15], [16], [17, 19] 32 | */ 33 | 34 | /** 35 | * Definition for singly-linked list. 36 | * struct ListNode { 37 | * int val; 38 | * ListNode *next; 39 | * ListNode(int x) : val(x), next(NULL) {} 40 | * }; 41 | */ 42 | 43 | ListNode* mergeKLists(vector& lists) 44 | { 45 | priority_queue, LessThanByVal> q; 46 | ListNode* sentinel = new ListNode(0); 47 | ListNode* cur = sentinel; 48 | 49 | for (int i = 0; i < lists.size(); i++) 50 | { 51 | if (lists[i] != nullptr) 52 | { 53 | q.push(lists[i]); 54 | } 55 | } 56 | 57 | while (!q.empty()) 58 | { 59 | ListNode* nextElement = q.top(); 60 | cur->next = nextElement; 61 | cur = cur->next; 62 | q.pop(); 63 | if (nextElement->next != nullptr) q.push(nextElement->next); 64 | } 65 | 66 | return sentinel->next; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/028 - implementStrstr.cpp: -------------------------------------------------------------------------------- 1 | #include "028 - implementStrstr.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "28. Implement Strstr" for the problem statement. 9 | https://leetcode.com/problems/implement-strstr/description/ 10 | 11 | Solution: 12 | Fairly simple brute force search. For each possible starting point, check to see if the needle completes itself. 13 | Immediately return the index if it does so. On a mismatch, disregard the remaining characters and try the next index. 14 | 15 | Let N be the length of the haystack, and K be the length of the needle 16 | Time Complexity: O(NK) 17 | Space Complexity: O(1) 18 | 19 | Be Aware: 20 | -LeetCode Discussion for this problem has a neat Knuth-Morris-Pratt algorithm that is theoretically faster than this solution. In practice, both complete the test cases in around 4 ms. 21 | -Don't forget to account for the empty needle case! 22 | -Time Complexity: O(H * L), where H is the length of the haystack and L is the length of the needle. 23 | 24 | */ 25 | 26 | int Solution028::strStr(string haystack, string needle) 27 | { 28 | int needle_len = needle.length(); 29 | int haystk_len = haystack.length(); 30 | 31 | if (needle_len == 0) return 0; 32 | for (int i = 0; i <= haystk_len - needle_len; i++) 33 | { 34 | for (int j = 0; j < needle_len; j++) 35 | { 36 | if (haystack[i + j] != needle[j]) break; 37 | if (j == needle_len - 1) return i; 38 | } 39 | } 40 | 41 | return -1; 42 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/033 - searchInRotatedSortedArray.cpp: -------------------------------------------------------------------------------- 1 | #include "033 - searchInRotatedSortedArray.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "33. Search in Rotated Sorted Array" for the problem statement. 9 | https://leetcode.com/problems/search-in-rotated-sorted-array/description/ 10 | Please refer to "153. Find Minimuim in Rotated Sorted Array" for more information on the algorithm to find the minimum in a rotated sorted array. 11 | 12 | Solution: 13 | Perform a binary search for the location that the array was rotated to, then treat the array as if it was a normal one by doing a normal binary search accounting for the offset. 14 | We achieve this by finding the true middle in our actual search by adding the amount rotated mod by the size of the array to get the midpoint as if the array started from the offset. 15 | 16 | Let N be the size of the input array 17 | Time Complexity: O(logN), two binary searches 18 | Space Complexity: O(1), solution performed iteratively and not recursively with no additional data structures 19 | 20 | Be Aware: 21 | -This solution can be coded recursively. If the solution isn't tail recursive, what does this mean for the space complexity once we start considering the call stack? 22 | -Why are we applying the modulus operator when setting the mid_rotated? 23 | 24 | Tests: 25 | Empty Array 26 | [7,8,9,1,2,3] 27 | [1,2,3,4,5,6] 28 | [1] 29 | [2,1] 30 | [1,2,3,4,5,6,7] 31 | [4,5,6,7,1,2,3] 32 | [2,3,4,5,6,7,1] 33 | */ 34 | 35 | int Solution033::search(vector& nums, int target) 36 | { 37 | int low = 0; 38 | int high = nums.size() - 1; 39 | while (low < high) 40 | { 41 | int mid = low + (high - low) / 2; 42 | if (nums[mid] > nums[high]) low = mid + 1; 43 | else high = mid; 44 | } 45 | 46 | int rotation = low; 47 | low = 0; 48 | high = nums.size() - 1; 49 | 50 | while (low <= high) 51 | { 52 | int mid = low + (high - low) / 2; 53 | int mid_rotated = (mid + rotation) % nums.size(); 54 | if (nums[mid_rotated] == target) return mid_rotated; 55 | if (nums[mid_rotated] < target) low = mid + 1; 56 | else high = mid - 1; 57 | } 58 | 59 | return -1; 60 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/036 - validSudoku.cpp: -------------------------------------------------------------------------------- 1 | #include "036 - validSudoku.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "36. Valid Sudoku" for the problem statement. 9 | https://leetcode.com/problems/valid-sudoku/description/ 10 | 11 | Solution: 12 | We create three 9x9 arrays of booleans. 13 | Each row represents one of the 9 rows, columns, or squares of the board 14 | Each index represents whether that index + 1 has been used in the board yet. (e.g. rowUsed[4][7] represents whether 8 has been used yet in the 5th row). 15 | 16 | We iterate through the characters in the board. If we encounter a number, we check to see if it has been used for its row, column, or square yet. 17 | If any, return false. 18 | Otherwise, we update all three to be used. 19 | 20 | If we make it through all squares without issue, then we can safely return true. 21 | 22 | Because the size of the Sudoku board is fixed to a 9x9 grid, we are using constant space and time for this function. 23 | Time Complexity: O(1) 24 | Space Complexity: O(1) 25 | 26 | Be Aware: 27 | -k might be calculated a bit strangely here, but it is simply an equation that is used to ensure that elements within their square all map to the same numbering: 28 | 29 | 0 1 2 30 | 3 4 5 31 | 6 7 8 32 | 33 | Tests: 34 | A valid board that has some spaces 35 | A valid board that is completely empty 36 | A valid board that is completely solved 37 | An invalid board 38 | */ 39 | 40 | bool Solution036::isValidSudoku(vector>& board) 41 | { 42 | bool rowUsed[9][9] = { 0 }, colUsed[9][9] = { 0 }, squareUsed[9][9] = { 0 }; 43 | 44 | for (int i = 0; i < board.size(); i++) 45 | { 46 | for (int j = 0; j < board[i].size(); j++) 47 | { 48 | if (board[i][j] != '.') 49 | { 50 | int index = board[i][j] - '0' - 1, k = i / 3 * 3 + j / 3; 51 | if (rowUsed[i][index] || colUsed[j][index] || squareUsed[k][index]) return false; 52 | 53 | rowUsed[i][index] = colUsed[j][index] = squareUsed[k][index] = true; 54 | } 55 | } 56 | } 57 | 58 | return true; 59 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/041 - firstMissingPositive.cpp: -------------------------------------------------------------------------------- 1 | #include "041 - firstMissingPositive.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Hard 8 | Please refer to "41. First Missing Positive" for the problem statement. 9 | https://leetcode.com/problems/first-missing-positive/description/ 10 | 11 | Solution: 12 | The problem stipulates that we cannot use any extra space, yet the problem would be so trivial if we could! 13 | Think: for an array of size n, the first missing positive must be n + 1 at the very most (assuming the array contains identically the first n positive integers. 14 | Think, we simply initialize an array of bools of the same length as the input. 15 | Then, iterate through the input array. Every time we encounter a value within the range, we set the bool corresponding to its index to true. 16 | Then, iterate through the bool array, and return the index of the first index to contain false, else we return n + 1 since that's the first missing positive. 17 | 18 | Time Complexity: O(N) 19 | Space Complexity: O(N) 20 | 21 | How do we make this solution better? 22 | Turns out, we can just use the existing array and swap values in place as we go along, using the exact same principle! 23 | Numbers above n and 0 or less are irrelevant, since none of them can possibly be the first missing positive. 24 | 25 | Whenever we consider the ith element and are about to make a swap, we need to take care that we address two things: 26 | -The item that gets swapped with the ith item may also itself require swapping. 27 | -If the item that got swapped with the ith item is a duplicate of the ith item, we could get stuck in an endless loop of swaps. We don't want that. 28 | 29 | Addressing both issues in the conditional of the while loop we have ourselves an O(N) time, O(1) space solution! 30 | 31 | Let N be the size of the input vector. 32 | Time Complexity: O(N), note that the inner while loop will perform at most N swaps in total for the entire execution of the function. 33 | Space Complexity: O(1) 34 | 35 | Be Aware: 36 | -This solution modifies the input vector. Would we still be able to have an O(1) space solution if we weren't allowed to? 37 | -Make sure to understand why this solution is still O(N) time despite the fact that it has a nested while loop.\ 38 | 39 | Tests: 40 | [1,2,3,4] 41 | [] 42 | [2] 43 | [3, -2, 1, 4, 5, -22] 44 | [8, 12, 14, -1, 0, 2] 45 | */ 46 | 47 | 48 | int Solution041::firstMissingPositive(vector& nums) 49 | { 50 | for (int i = 0; i < nums.size(); i++) 51 | { 52 | while (nums[i] > 0 && nums[i] <= nums.size() && nums[nums[i] - 1] != nums[i]) 53 | { 54 | swap(nums[i], nums[nums[i] - 1]); 55 | } 56 | } 57 | 58 | for (int j = 0; j < nums.size(); j++) 59 | { 60 | if (nums[j] != j + 1) 61 | return j + 1; 62 | } 63 | 64 | return nums.size() + 1; 65 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/045 - jumpGameII.cpp: -------------------------------------------------------------------------------- 1 | #include "045 - jumpGameII.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Hard 8 | Please refer to "45. Jump Game II" for the problem statement. 9 | https://leetcode.com/problems/jump-game-ii/description/ 10 | 11 | Solution: 12 | We utilize a greedy approach. It's very similar to Jump Game I. However, this time we know for sure we can reach the end. 13 | The trick is to keep track of the furthest distance you can get on your current jump, and a tally of jumps that you have performed. 14 | Whenever we reach the furthest index we can do in one jump, we increment the jumps counter since further distance requires another jump. 15 | The furthest distance that we can reach at this point is the new furthest distance we can achieve with the next jump. 16 | 17 | Time Complexity: O(N) 18 | Space Complexity: O(1) 19 | 20 | Credit to LeetCode user ChengZhang for this delightful solution! 21 | 22 | Tests: 23 | TODO 24 | */ 25 | 26 | 27 | int Solution045::jump(vector& nums) 28 | { 29 | int jumps = 0, curEnd = 0, curFarthest = 0; 30 | for (int i = 0; i < nums.size() - 1; i++) 31 | { 32 | curFarthest = max(nums[i] + i, curFarthest); 33 | //We reached the last index that we can reach for this jump 34 | if (i == curEnd) 35 | { 36 | jumps++; 37 | curEnd = curFarthest; 38 | } 39 | } 40 | 41 | return jumps; 42 | } 43 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/049 - groupAnagrams.cpp: -------------------------------------------------------------------------------- 1 | #include "049 - groupAnagrams.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "49. Group Anagrams" for the problem statement. 9 | https://leetcode.com/problems/group-anagrams/description/ 10 | 11 | Solution: 12 | Credit to jianchao.li.fighter for the intuition for using countingSort for the solution, something not initially in my original solution. 13 | Check it out here: https://discuss.leetcode.com/topic/21038/10-lines-76ms-easy-c-solution-updated-function-signature 14 | 15 | We want to group words that are anagrams of each other together. 16 | It makes sense to store anagrams in a multiset (assuming that duplicates can appear in the original group of words). 17 | What do we use to separate groups out? It makes sense to use a hash table... 18 | But then, what do we use for the key? Well, it turns out we can use the letters of the anagram groups sorted by increasing order, because that is precisely what groups the anagrams together. 19 | 20 | This can be achieved very efficiently with counting sort, though a standard sorting algorithm is perfectly fine, and not much better. 21 | 22 | Once we have this data structure selected, we simply iterate through our vector of strings and insert each one into the appropriate multiset. 23 | Then, we undergo some processing to return the data in a vector of vector of strings, like the function wants. 24 | 25 | Let N be the number of strings in the input vector. 26 | Time Complexity: O(NlogN), to insert each string into the hashmap of multisets. Will generally perform much better than this. 27 | Space Complexity: O(N), each string is inserted into our data structure one time. 28 | 29 | Be Aware: 30 | -Why use counting sort instead of a standard sort? A: Technically, it produces a better runtime on the length of the string in characters. 31 | 32 | Tests: 33 | -No strings 34 | -"eat", "tea", "tan", "ate", "nat", "bat" 35 | -"tan", "tan" 36 | -"apple", "orange", "banana", "elppa", "nanaba" 37 | -All the words that appear in Webster's dictionary. :P 38 | */ 39 | 40 | vector> Solution049::groupAnagrams(vector& strs) 41 | { 42 | unordered_map> map; 43 | for (int i = 0; i < strs.size(); i++) 44 | { 45 | string temp = stringSort(strs[i]); 46 | map[temp].insert(strs[i]); 47 | } 48 | 49 | vector> result; 50 | for (auto m : map) 51 | { 52 | vector anagram(m.second.begin(), m.second.end()); 53 | result.push_back(anagram); 54 | } 55 | 56 | return result; 57 | } 58 | 59 | string Solution049::stringSort(string& s) 60 | { 61 | vector charCount(26, 0); 62 | for (int i = 0; i < s.size(); i++) 63 | { 64 | charCount[s[i] - 'a']++; 65 | } 66 | 67 | string result = ""; 68 | result.reserve(s.size()); 69 | for (int j = 0; j < 26; j++) 70 | { 71 | for (int k = 0; k < charCount[j]; k++) 72 | { 73 | result += j + 'a'; 74 | } 75 | } 76 | 77 | return result; 78 | } 79 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/054 - spiralMatrix.cpp: -------------------------------------------------------------------------------- 1 | #include "054 - spiralMatrix.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Refer to "54. Spiral Matrix" for the problem statement. 9 | https://leetcode.com/problems/spiral-matrix/description/ 10 | 11 | Solution: 12 | We traverse the 2D array like we would follow it on paper: start at the top left corner and just wrap around. 13 | We keep track of a left, right, top, and bottom index. Every time we complete a "line" in our spiral traversal, we modify the indices to match. 14 | The final solution has a time complexity of O(MN), which is unavoidable because we must visit every index once anyway. 15 | 16 | Let M x N be the dimensions of the matrix. 17 | Time Complexity: O(MN), each element must be visited once 18 | Space Complexity: O(MN), to hold the result. O(1) additional space needed, since it is just 4 integers 19 | 20 | Be Aware: 21 | -This is an exercise in traversal and index tracking; there are a variety of ways to do this. 22 | -Watch out for out of bound errors. 23 | 24 | Test Cases: 25 | Empty array. 26 | Array with one row 27 | Array with one element 28 | Array with multiple columns of 1 item rows 29 | 5x5 30 | 5x6 31 | 6x6 32 | 6x5 33 | */ 34 | vector Solution054::spiralOrder(vector>& matrix) 35 | { 36 | vector result; 37 | if (matrix.size() == 0) return result; 38 | 39 | int top = 0; 40 | int bottom = matrix.size() - 1; 41 | int left = 0; 42 | int right = matrix[0].size() - 1; 43 | 44 | while (top <= bottom && left <= right) 45 | { 46 | int r = left; 47 | while (r <= right) 48 | { 49 | result.push_back(matrix[top][r]); 50 | r++; 51 | } 52 | top++; 53 | if (top > bottom) return result; 54 | int d = top; 55 | while (d <= bottom) 56 | { 57 | result.push_back(matrix[d][right]); 58 | d++; 59 | } 60 | right--; 61 | if (left > right) return result; 62 | int l = right; 63 | while (l >= left) 64 | { 65 | result.push_back(matrix[bottom][l]); 66 | l--; 67 | } 68 | bottom--; 69 | int u = bottom; 70 | while (u >= top) 71 | { 72 | result.push_back(matrix[u][left]); 73 | u--; 74 | } 75 | left++; 76 | } 77 | 78 | return result; 79 | 80 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/055 - jumpGame.cpp: -------------------------------------------------------------------------------- 1 | #include "055 - jumpGame.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "55. Jump Game" for the problem statement. 9 | https://leetcode.com/problems/jump-game/description/ 10 | 11 | Solution: 12 | Utilize a greedy approach. Begin at the start, initialize the max index you can reach from the start, and iterate through the array. 13 | If at any point the number stored at an index would push back how far you can move, update the max reachable index. 14 | If you can no longer iterate any further and you have passed the max index without exceeding the target (the end), then it isn't possible to reach the end. 15 | 16 | Let N be the size of the input array. 17 | Time Complexity: O(N), currentMax is set to nums.size() - 2 and reached by i, but the end is not reached 18 | Space Complexity: O(1), just some integers to keep track of locations 19 | 20 | Be Aware: 21 | -This problem is a good demonstration of how to utilize looping to get a good solution. 22 | -This is a good example of a greedy algorithm. Why is it intuitively good to try a greedy solution in this case? 23 | 24 | Tests: 25 | -Reachable 26 | -Unreachable 27 | */ 28 | bool Solution055::canJump(vector& nums) 29 | { 30 | int target = nums.size() - 1; 31 | int currentMax = 0; 32 | 33 | int i = 0; 34 | while (i <= currentMax) 35 | { 36 | if (i + nums[i] > currentMax) currentMax = i + nums[i]; 37 | if (i >= target) return true; 38 | i++; 39 | } 40 | 41 | return false; 42 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/056 - mergeIntervals.cpp: -------------------------------------------------------------------------------- 1 | #include "056 - mergeIntervals.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "56. Merge Intervals" for the problem statement. 9 | https://leetcode.com/problems/merge-intervals/description/ 10 | 11 | Solution: 12 | We sort the interval vector by increasing start time. 13 | Then, beginning at the first interval, we keep merging start times that fall within the end bounds, and updating the end bounds if it increases. 14 | Whenver we encounter an interval that is outside of the end bounds, we set a new start and end bound for another interval that will be in our result. 15 | 16 | Let N be number of intervals in the input array 17 | Time Complexity: O(NlogN), for sorting the array 18 | Space Complexity: O(N), for the result 19 | 20 | Be Aware: 21 | -Functions that are intended to be used by std::sort must be declared as static in c++ 22 | -This assumes that the std::sort function implements a sorting algorithm that runs in NlogN time 23 | -Use the keyword const if you want the function to promise that it won't modify the input contents. 24 | */ 25 | 26 | /** 27 | * Definition for an interval. 28 | * struct Interval { 29 | * int start; 30 | * int end; 31 | * Interval() : start(0), end(0) {} 32 | * Interval(int s, int e) : start(s), end(e) {} 33 | * }; 34 | */ 35 | 36 | static bool sortByStart(const Interval& a, const Interval& b) 37 | { 38 | return a.start < b.start; 39 | } 40 | 41 | vector Solution056::merge(vector& intervals) 42 | { 43 | vector result; 44 | if (intervals.size() == 0) return result; 45 | sort(intervals.begin(), intervals.end(), sortByStart); 46 | 47 | int curStart = intervals[0].start; 48 | int curEnd = intervals[0].end; 49 | for (int i = 1; i < intervals.size(); i++) 50 | { 51 | if (intervals[i].start > curEnd) 52 | { 53 | Interval toAdd(curStart, curEnd); 54 | result.push_back(toAdd); 55 | curStart = intervals[i].start; 56 | curEnd = intervals[i].end; 57 | } 58 | else if (intervals[i].end > curEnd) curEnd = intervals[i].end; 59 | } 60 | 61 | Interval straggler(curStart, curEnd); 62 | result.push_back(straggler); 63 | 64 | return result; 65 | } 66 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/057 - insertInterval.cpp: -------------------------------------------------------------------------------- 1 | #include "057 - insertInterval.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Hard 8 | Please refer to "57. Insert Interval" for the problem statement. 9 | https://leetcode.com/problems/insert-interval/description/ 10 | 11 | Solution: 12 | We are given that the intervals are sorted by start time. 13 | Thus, we can iterate through the array of intervals once to insert our new interval, such that our array is still in sorted order. 14 | The issue then remains that merging might have to occur. 15 | 16 | They essentially reduce to these two situations: 17 | -The interval right before where we inserted the interval might have an end that surpasses the start point of our inserted interval, requiring merging. 18 | -Every interval after the interval that we inserted might have a start point that is surpassed by the end point of our inserted interval, also requring merging. 19 | 20 | Fortunately for us, this can be done in a second pass through the array. 21 | 22 | Time Complexity: O(N) 23 | Space Complexity: O(1) 24 | 25 | Be Aware: 26 | -Don't forget to account for the case where our array of intervals began as an empty array! 27 | -Make sure you understand the time complexity of your STL functions. In this case, vector insert is linear on number of items inserted and items after its insertion location. Because we insert once at most and it could be at the start, it still falls within O(N) time. 28 | -Also note that {[1,5], [6, 8]} is a valid interval set that doesn't require any merging. 29 | 30 | Tests: 31 | Empty vector 32 | {[1, 3], [6, 7]}, [3, 4] 33 | {[1, 3], [7, 10], [12, 15]} [4, 24] 34 | 35 | */ 36 | 37 | /** 38 | * Definition for an interval. 39 | * struct Interval { 40 | * int start; 41 | * int end; 42 | * Interval() : start(0), end(0) {} 43 | * Interval(int s, int e) : start(s), end(e) {} 44 | * }; 45 | */ 46 | 47 | vector Solution057::insert(vector& intervals, Interval newInterval) 48 | { 49 | if (intervals.empty()) 50 | { 51 | intervals.insert(intervals.begin(), newInterval); 52 | return intervals; 53 | } 54 | 55 | bool insertAtEnd = true; 56 | for (int i = 0; i < intervals.size(); i++) 57 | { 58 | if (intervals[i].start > newInterval.start) 59 | { 60 | intervals.insert(intervals.begin() + i, newInterval); 61 | insertAtEnd = false; 62 | break; 63 | } 64 | } 65 | if (insertAtEnd) intervals.insert(intervals.end(), newInterval); 66 | 67 | for (int j = 0; j < intervals.size() - 1; j++) 68 | { 69 | if (intervals[j].end >= intervals[j + 1].start) 70 | { 71 | intervals[j].end = max(intervals[j].end, intervals[j + 1].end); 72 | intervals.erase(intervals.begin() + j + 1, intervals.begin() + j + 2); 73 | j--; 74 | } 75 | } 76 | 77 | return intervals; 78 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/066 - plusOne.cpp: -------------------------------------------------------------------------------- 1 | #include "066 - plusOne.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "66. Plus One" for the problem statement. 9 | https://leetcode.com/problems/plus-one/description/ 10 | 11 | Solution: 12 | Initialize a carry to 1 to represent the 1 that we are adding, then propagate that carry through the digits array. 13 | 14 | Time Complexity: O(N), where N is the size of the digits vector 15 | Space Complexity: O(N), since a copy is made. If the intention is to modify the input array, this can be changed to use O(1) space 16 | Be Aware: 17 | -Don't forget to consider that you might need to add a carry, if it remains at the end. 18 | -There is no push_front function in the C++ vector library. 19 | Test Cases: 20 | 1 21 | 0 22 | 9 23 | 9, 9 24 | 1, 9, 0 25 | 2, 1, 9 26 | 27 | */ 28 | vector Solution066::plusOne(vector& digits) 29 | { 30 | vector result; 31 | int carry = 1; 32 | for (int i = digits.size() - 1; i >= 0; i--) 33 | { 34 | int sum = digits[i] + carry; 35 | result.push_back(sum % 10); 36 | carry = sum / 10; 37 | } 38 | 39 | if (carry) result.push_back(carry); 40 | reverse(result.begin(), result.end()); 41 | return result; 42 | } 43 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/070 - climbingStairs.cpp: -------------------------------------------------------------------------------- 1 | #include "070 - climbingStairs.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "70. Climbing Stairs" for the problem statement. 9 | https://leetcode.com/problems/climbing-stairs/description/ 10 | 11 | Solution: 12 | This is a classic dynamic programming problem. For any stair number i, we arrived there with 1 step from the step below, or with 2 steps from 2 below. 13 | Thus, if that is denoted as OPT[n], we can use the recurrence OPT[n] = OPT[n - 1] + OPT[n - 2]. 14 | Note that the solutions for each part are mutually exclusive because all of the ones in OPT[n - 1] get a 1 step at the end and all of the ones in OPT[n - 2] get a 2 step at the end. 15 | 16 | Time Complexity: O(N), where N is the integer number specified by the input. 17 | Space Complexity: O(1) 18 | 19 | Base case for 1 step is 1 since you can only take a 1 step move. 20 | Base case for 2 step is 2 since you can do 1,1 or a single 2 step. 21 | 22 | Be Aware: 23 | -Though the question is ranked Easy, you might have some trouble if you haven't yet learned Dynamic Programming. It's a very neat topic! 24 | 25 | Tests: 26 | 1 27 | 2 28 | 3 29 | 6 30 | */ 31 | int Solution070::climbStairs(int n) 32 | { 33 | 34 | if (n == 1) return 1; 35 | if (n == 2) return 2; 36 | 37 | int twoStepsDown = 1; 38 | int oneStepDown = 2; 39 | int result = 0; 40 | 41 | for (int i = 3; i <= n; i++) 42 | { 43 | result = twoStepsDown + oneStepDown; 44 | twoStepsDown = oneStepDown; 45 | oneStepDown = result; 46 | } 47 | 48 | return result; 49 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/074 - searchA2DMatrix.cpp: -------------------------------------------------------------------------------- 1 | #include "074 - searchA2DMatrix.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | 7 | /* 8 | Difficulty: Medium 9 | Please refer to "74. Search a 2D Matrix" for the problem statement. 10 | https://leetcode.com/problems/search-a-2d-matrix/description/ 11 | 12 | Solution: 13 | The basic principle is a 2 layer binary search. First we find the row that the target would have to exist in. 14 | Then we binary search within that row (if we find it, otherwise we'll have already returned) to try to find the target. 15 | 16 | Let M be the number of rows in the matrix, and N be the number of columns in the matrix 17 | Time Complexity: O(logM) + O(logN) 18 | Space Complexity: O(1) 19 | 20 | Be Aware: 21 | -Though the solution has two nested while loops, the time complexity is still posted above. 22 | -The reason why it isn't O(logM)O(logN) is because we are only binary searching by column in at most one row. 23 | -Note that O(logM) + O(logM) = O(log(MN)), which is the log of the number of items in the matrix, the same time complexity as if we were binary searching a sorted array. 24 | 25 | Tests: 26 | Target in (4,4) of 4x4 matrix 27 | Target greater than largest value of matrix 28 | Target smaller than smallest value of matrix 29 | Target not in matrix, but between last element of row 1 and first element of row 2 30 | Target in (1,1) of 4x4 matrix 31 | Target in (2,3) of 4x4 matrix 32 | Target in (5,1) of 10x1 matrix 33 | 34 | */ 35 | 36 | bool Solution074::searchMatrix(vector>& matrix, int target) 37 | { 38 | int m = matrix.size(); 39 | if (m == 0) return false; 40 | int n = matrix[0].size(); 41 | if (n == 0) return false; 42 | 43 | int m_low = 0; 44 | int m_high = m - 1; 45 | 46 | while (m_low <= m_high) 47 | { 48 | int m_mid = m_low + (m_high - m_low) / 2; 49 | if (matrix[m_mid][n - 1] < target) m_low = m_mid + 1; 50 | else if (matrix[m_mid][0] > target) m_high = m_mid - 1; 51 | else 52 | { 53 | int n_low = 0; 54 | int n_high = n - 1; 55 | while (n_low <= n_high) 56 | { 57 | int n_mid = n_low + (n_high - n_low) / 2; 58 | if (matrix[m_mid][n_mid] == target) return true; 59 | else if (matrix[m_mid][n_mid] > target) n_high = n_mid - 1; 60 | else n_low = n_mid + 1; 61 | } 62 | break; 63 | } 64 | } 65 | 66 | return false; 67 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/075 - sortColors.cpp: -------------------------------------------------------------------------------- 1 | #include "075 - sortColors.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "75. Sort Colors" for the problem statement. 9 | https://leetcode.com/problems/sort-colors/description/ 10 | 11 | Solution: 12 | Instead of actually sorting, because there are so few different kinds of elements in the data set, we just keep a count of each one and then add them in via simple loops afterwards. 13 | 14 | Time Complexity: O(N) 15 | Space Complexity: O(1) 16 | 17 | Be Aware: 18 | -Normally a sorting algorithm can at best be O(NlogN), because O(N) time is only enough to iterate through an unsorted array. However, in this case we achieve a better solution since we know information about the data set. 19 | 20 | Tests: 21 | [] 22 | [1] 23 | [0] 24 | [2] 25 | [1,0,2] 26 | [0,0,1,2,2,2] 27 | [1,0,1,2,1,2] 28 | */ 29 | 30 | 31 | void Solution075::sortColors(vector& nums) 32 | { 33 | int reds = 0, whites = 0, blues = 0; 34 | for (int i = 0; i < nums.size(); i++) 35 | { 36 | switch (nums[i]) 37 | { 38 | case 0: 39 | reds++; 40 | break; 41 | case 1: 42 | whites++; 43 | break; 44 | case 2: 45 | blues++; 46 | break; 47 | default: 48 | return; 49 | } 50 | } 51 | 52 | int index = 0; 53 | for (int r = 0; r < reds; r++) 54 | { 55 | nums[index] = 0; 56 | index++; 57 | } 58 | 59 | for (int w = 0; w < whites; w++) 60 | { 61 | nums[index] = 1; 62 | index++; 63 | } 64 | 65 | for (int b = 0; b < blues; b++) 66 | { 67 | nums[index] = 2; 68 | index++; 69 | } 70 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/078 - subsets.cpp: -------------------------------------------------------------------------------- 1 | #include "078 - subsets.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "78. Subsets" for the problem statement. 9 | https://leetcode.com/problems/subsets/description/ 10 | 11 | Solution: 12 | Backtracking 13 | Each number either exists in a subset or it doesn't. We iterate through the numbers. 14 | -At index i, we have all the subsets generated from 1 to i - 1. These represent half of the subsets in the range 1 to i. 15 | -The other half is simply this half, except with the number at index i included in each one. 16 | -Thus, for each iteration we go back to what we have in the solution and add items appropriately. 17 | 18 | Time Complexity: O(2^N), where N is the number of items in the input vector. 2^N subsets are generated. 19 | -Remember each number stored at the ith index is either in a given subset, or not. 20 | Space Complexity: O(2^N), to hold the result 21 | 22 | Be aware: 23 | -These kinds of problems can be intimidating because there are so many outputs to keep track of. Keep a level head and try to find a procedure to generate what you need! 24 | -Set theory is a very interesting topic in Discrete Mathematics. Knowledge of this topic can help with some of the more mathy coding questions. 25 | 26 | Tests: 27 | [] 28 | [1,2,3,4] 29 | [2,3,5] 30 | */ 31 | 32 | vector> Solution078::subsets(vector& nums) 33 | { 34 | vector> result; 35 | result.push_back({}); 36 | 37 | int last = result.size(); 38 | for (int i = 0; i < nums.size(); i++) 39 | { 40 | for (int j = 0; j < last; j++) 41 | { 42 | vector element = result[j]; 43 | element.push_back(nums[i]); 44 | result.push_back(element); 45 | } 46 | last = result.size(); 47 | } 48 | 49 | return result; 50 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/086 - partitionList.cpp: -------------------------------------------------------------------------------- 1 | #include "086 - partitionList.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Medium 6 | Please refer to "86. Partition List" for the problem statement. 7 | https://leetcode.com/problems/partition-list/description/ 8 | 9 | Solution: 10 | Simply have two linked lists, one representing the early half and one representing the later half, and iterate once through the linked list and assign each node in order. 11 | Then, it's simply a matter of attaching one half to another to get the solution. 12 | 13 | Let N be the number of nodes in the linked list 14 | Time Complexity: O(N) 15 | Space Complexity: O(1) 16 | 17 | Be Aware: 18 | -Note the use of sentinel nodes to make pointer management and special case considerations a little easier than before. 19 | */ 20 | 21 | /** 22 | * Definition for singly-linked list. 23 | * struct ListNode { 24 | * int val; 25 | * ListNode *next; 26 | * ListNode(int x) : val(x), next(NULL) {} 27 | * }; 28 | */ 29 | 30 | ListNode* Solution086::partition(ListNode* head, int x) 31 | { 32 | ListNode *leftPartSentinel = new ListNode(0); 33 | ListNode *rightPartSentinel = new ListNode(0); 34 | ListNode *leftCounter = leftPartSentinel; 35 | ListNode *rightCounter = rightPartSentinel; 36 | 37 | while (head != nullptr) 38 | { 39 | if (head->val < x) 40 | { 41 | leftCounter->next = head; 42 | leftCounter = leftCounter->next; 43 | } 44 | else 45 | { 46 | rightCounter->next = head; 47 | rightCounter = rightCounter->next; 48 | } 49 | head = head->next; 50 | } 51 | rightCounter->next = nullptr; 52 | leftCounter->next = rightPartSentinel->next; 53 | 54 | return leftPartSentinel->next; 55 | } 56 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/098 - validateBinarySearchTree.cpp: -------------------------------------------------------------------------------- 1 | #include "098 - validateBinarySearchTree.h" 2 | 3 | /* 4 | Difficulty: Medium 5 | Please refer to "98. Validate Binary Search Tree" for the problem statement. 6 | https://leetcode.com/problems/validate-binary-search-tree/description/ 7 | 8 | Solution: 9 | A binary search tree will output its values in sorted order if we perform an inorder traversal. 10 | So, in order to validate it, we simply perform such a traversal, tracking the value stored in the previous node in the traversal, and returning false if at any point the order criteria fails. 11 | 12 | Let N be the number of nodes in the tree. 13 | Time Complexity: O(N), a traversal of the entire tree. 14 | Space Complexity: TODO 15 | 16 | Be Aware: 17 | -Why does an inorder traversal produce the contents of a binary search tree in order (besides the name, of course). 18 | -What if the tree was just a binary tree, and not a binary search tree? 19 | 20 | Tests: 21 | Empty Tree 22 | 1 Node Tree 23 | Valid Tree 24 | Tree with all the same value 25 | */ 26 | 27 | /** 28 | * Definition for a binary tree node. 29 | * struct TreeNode { 30 | * int val; 31 | * TreeNode *left; 32 | * TreeNode *right; 33 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 34 | * }; 35 | */ 36 | 37 | bool Solution098::isValidBST(TreeNode* root) 38 | { 39 | TreeNode* prev = nullptr; 40 | return validate(root, prev); 41 | } 42 | 43 | bool Solution098::validate(TreeNode* root, TreeNode* &prev) 44 | { 45 | if (root == nullptr) return true; 46 | if (!validate(root->left, prev)) return false; 47 | if (prev != nullptr && prev->val >= root->val) return false; 48 | prev = root; 49 | return validate(root->right, prev); 50 | } 51 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/100 - sameTree.cpp: -------------------------------------------------------------------------------- 1 | #include "100 - sameTree.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Easy 6 | Please refer to "100. Same Tree" for the problem statement. 7 | https://leetcode.com/problems/same-tree/description/ 8 | 9 | Solution: 10 | If both pointers are nullptr, then it is true as a base case. 11 | After this check if either of them are, then it must be false by structure. 12 | Otherwise just check the current pair's value, as well as if these properties hold true for the left and right subtrees. 13 | 14 | Let M be the number of nodes in tree p, and N be the number of nodes in tree q 15 | Time Complexity: O(min(M, N)), if one tree is smaller then worst case we find out they aren't the same tree after all of the nodes in the smaller tree have been tested 16 | Space Complexity: O(1), unless counting space on call stack for recursive call, then O(min(M, N)), if input is two binary trees that are the same except for the leaf, and each non-leaf has only 1 child node. 17 | 18 | Be Aware: 19 | Recursive calls need to store information on the call stack. That is, if a call to a recursive function hasn't returned yet, it needs to store information until it does. 20 | What this means is that if a recursive call goes many levels deep and is not tail recursive, then the space on the call stack will pile up. 21 | 22 | Tests: 23 | -Empty tree 24 | -Single node same tree 25 | -Single node different tree 26 | -Tree different by structure 27 | -Tree different by only value 28 | -Tree different by both 29 | */ 30 | 31 | /** 32 | * Definition for a binary tree node. 33 | * struct TreeNode { 34 | * int val; 35 | * TreeNode *left; 36 | * TreeNode *right; 37 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 38 | * }; 39 | */ 40 | 41 | bool Solution100::isSameTree(TreeNode* p, TreeNode* q) 42 | { 43 | if (p == nullptr && q == nullptr) return true; 44 | if (p == nullptr || q == nullptr) return false; 45 | 46 | return (p->val == q->val) && isSameTree(p->left, q->left) && isSameTree(p->right, q->right); 47 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/101 - symmetricTree.cpp: -------------------------------------------------------------------------------- 1 | #include "101 - symmetricTree.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Easy 6 | Please refer to "101. Symmetric Tree" for the problem statement. 7 | https://leetcode.com/problems/symmetric-tree/description/ 8 | 9 | Solution: 10 | We simply take note of the fact that if we begin at the root and split down the middle, after the root's children 11 | the successive left nodes should match the opposite side's right nodes. 12 | If at any point there is a null pointer discrepancy then the tree is asymmetrical by structure. 13 | Otherwise we check the values of competing nodes and then pass the algorithm down, until we reach a pair of nullpointers. 14 | This is a classic recursive solution. 15 | 16 | Let N be the total number of nodes in the tree. 17 | Time Complexity: O(N), each node must be visited to prove symmetry 18 | Space Complexity: O(1), unless considering recursive call stack, in which case O(N). 19 | 20 | Be Aware: 21 | -Make sure you nail down your base cases! 22 | -When dealing with these problems, if the original function signature doesn't seem to be enough, write a helper! 23 | -Space complexity calculations can be tricky with recursive calls because of the way functions work on the call stack. Look up tail recursion to see ways to address this! 24 | -Can this function be optimized to be tail recursive? 25 | 26 | Tests: 27 | -Empty tree 28 | -Tree with just a root 29 | -Symmetric tree with a root and two children 30 | -Asymmetric tree with a root and two children 31 | -Asymmetric tree by structure 32 | -Asymmetric tree by value 33 | -Large symmetric tree for robustness. 34 | -Large tree with only one imperfection 35 | */ 36 | 37 | bool Solution101::isSymmetric(TreeNode* root) 38 | { 39 | if (root == nullptr) return true; 40 | return isSymmetricHelper(root->left, root->right); 41 | } 42 | 43 | bool Solution101::isSymmetricHelper(TreeNode* r1, TreeNode* r2) 44 | { 45 | if (r1 == nullptr && r2 == nullptr) return true; 46 | if (r1 == nullptr || r2 == nullptr) return false; 47 | 48 | if (r1->val != r2->val) return false; 49 | return isSymmetricHelper(r1->left, r2->right) && isSymmetricHelper(r1->right, r2->left); 50 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/102 - binaryTreeLevelOrderTraversal.cpp: -------------------------------------------------------------------------------- 1 | #include "102 - binaryTreeLevelOrderTraversal.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "102. Binary Tree Level Order Traversal" for the problem statement. 9 | https://leetcode.com/problems/binary-tree-level-order-traversal/description/ 10 | 11 | Solution: 12 | The key is to realize that in a standard level order traversal, you can use a queue to process the nodes in level order. 13 | We can utilize nullptr in the queue to signal level advancements. 14 | -Check the root for nullptr case 15 | -Push back a nullptr after the root pointer before diving into the for loop. 16 | -Don't add any left or right nodes if they are nullptr. 17 | 18 | Let N be the total number of nodes in the tree. 19 | Time Complexity: O(N), each node must be visited to be included in the traversal 20 | Space Complexity: O(N), complete binary tree with last row filled, right before processing of last level begins there will be N/2 nodes in the queue (each other node added 2 pointers while processing itself) 21 | 22 | Alterate Solution: 23 | Alternatively, you can have two queues, and use the emptying of one queue to signal moving to the next level. 24 | It is in the comments below, and also passed LeetCode's check. You can see for yourself if you'd like. 25 | This solution eliminates using nullptr as a sentinel but has the downside of additional complexity and an extra data structure. 26 | 27 | Be Aware: 28 | -Don't forget to pop your queue. front() doesn't take away the top item! 29 | -Why won't a stack work in this situation? 30 | 31 | Tests: 32 | -Empty tree 33 | -Tree with one item. 34 | -Any tree with significantly complex branching. 35 | -A complete tree. 36 | */ 37 | /** 38 | * Definition for a binary tree node. 39 | * struct TreeNode { 40 | * int val; 41 | * TreeNode *left; 42 | * TreeNode *right; 43 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 44 | * }; 45 | */ 46 | 47 | vector> Solution102::levelOrder(TreeNode* root) 48 | { 49 | vector> result; 50 | queue q; 51 | 52 | if (root == nullptr) return result; 53 | q.push(root); 54 | q.push(nullptr); 55 | 56 | vector level; 57 | while (!q.empty()) 58 | { 59 | TreeNode* front = q.front(); 60 | if (front != nullptr) 61 | { 62 | level.push_back(front->val); 63 | if (front->left != nullptr) q.push(front->left); 64 | if (front->right != nullptr) q.push(front->right); 65 | } 66 | else 67 | { 68 | result.push_back(level); 69 | level.clear(); 70 | if (q.size() != 1) q.push(nullptr); 71 | } 72 | q.pop(); 73 | } 74 | 75 | return result; 76 | } 77 | 78 | /* 79 | Alternate Solution 80 | vector> Solution102::levelOrder(TreeNode* root) 81 | { 82 | vector> result; 83 | queue q1; 84 | queue q2; 85 | 86 | if (root == nullptr) return result; 87 | q1.push(root); 88 | 89 | vector level; 90 | while (!q1.empty() || !q2.empty()) 91 | { 92 | if (!q1.empty()) 93 | { 94 | while (!q1.empty()) 95 | { 96 | TreeNode* front = q1.front(); 97 | if (front != nullptr) 98 | { 99 | level.push_back(front->val); 100 | if (front->left != nullptr) q2.push(front->left); 101 | if (front->right != nullptr) q2.push(front->right); 102 | } 103 | q1.pop(); 104 | } 105 | } 106 | else 107 | { 108 | while (!q2.empty()) 109 | { 110 | TreeNode* front = q2.front(); 111 | if (front != nullptr) 112 | { 113 | level.push_back(front->val); 114 | if (front->left != nullptr) q1.push(front->left); 115 | if (front->right != nullptr) q1.push(front->right); 116 | } 117 | q2.pop(); 118 | } 119 | } 120 | 121 | result.push_back(level); 122 | level.clear(); 123 | } 124 | 125 | return result; 126 | } 127 | */ 128 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/104 - maximumDepthOfBinaryTree.cpp: -------------------------------------------------------------------------------- 1 | #include "104 - maximumDepthOfBinaryTree.h" 2 | 3 | #include "config.h" 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "104. Maximum Depth of Binary Tree" for the problem statement. 9 | https://leetcode.com/problems/maximum-depth-of-binary-tree/description/ 10 | 11 | Solution: 12 | This solution takes a recursive approach to finding the result. 13 | Base case: If the root is a null pointer, then it doesn't contribute to the height of the tree and we return 0. 14 | Recursive step: The root is not a null pointer, so it contributes to the maximum possible depth. We return that added to the maximum of either the maxDepth of the left subtree or the right subtree. 15 | 16 | Let N be the number of nodes in the binary tree. 17 | Time Complexity: O(N), every node must be visited because it can potentially contribute to the maximum depth. 18 | Space Complexity: O(1), unless accounting for recursive call stack, in which case O(N) 19 | 20 | Be Aware: 21 | -As with all recursive problems, make sure that your recursive steps are reducing the problem closer to the base case. If not, your recursive solution may run forever! 22 | -As with all recursive problems, take note of whether your solution is tail recursive or not. If not then your recursive call might take space on the call stack! 23 | 24 | Tests: 25 | Empty tree 26 | Complete binary tree of depth 2 27 | Complete binary tree of depth 2, except with an additional leaf that increases the depth to 3 28 | Tree with just a root node 29 | Tree with many branches that end at different depths 30 | */ 31 | 32 | /** 33 | * Definition for a binary tree node. 34 | * struct TreeNode { 35 | * int val; 36 | * TreeNode *left; 37 | * TreeNode *right; 38 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 39 | * }; 40 | */ 41 | 42 | int Solution104::maxDepth(TreeNode* root) 43 | { 44 | if (root == nullptr) return 0; 45 | return 1 + max(maxDepth(root->left), maxDepth(root->right)); 46 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/111 - minimumDepthOfBinaryTree.cpp: -------------------------------------------------------------------------------- 1 | #include "111 - minimumDepthOfBinaryTree.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "111 - Minimum Depth of Binary Tree" for the problem statement. 9 | https://leetcode.com/problems/minimum-depth-of-binary-tree/description/ 10 | 11 | Solution: 12 | Check at the beginning to see if we were handed an empty tree. 13 | If not, then we call the helper. 14 | The helper checks to see if we are at a leaf. If so, return 1. 15 | Otherwise, depending on what children we have we perform a 1 + minDepthHelper call on each child. 16 | 17 | Let N be the number of nodes in the tree 18 | Time Complexity: O(N), consider a tree with 1 leaf, and every other node has one child. Every node will be visited to find this leaf. 19 | Space Complexity: O(1), unless considering recursive call stack, in which case O(N). 20 | 21 | Be Aware: 22 | -Be careful, remember that a node with any child is NOT a leaf node. How might this affect the way you write your base cases? 23 | -Can this be done more concisely? 24 | -This is a good example of how using a helper function makes things easier. 25 | -Can this function be made tail recursive? Why or why not? 26 | 27 | Tests: 28 | -Empty tree 29 | -Tree with one item. 30 | -Long snaking tree that is basically a linked list. 31 | -Big tree with leaves at varying depths. 32 | -Completely balanced binary tree. 33 | */ 34 | 35 | /** 36 | * Definition for a binary tree node. 37 | * struct TreeNode { 38 | * int val; 39 | * TreeNode *left; 40 | * TreeNode *right; 41 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 42 | * }; 43 | */ 44 | 45 | int Solution111::minDepth(TreeNode* root) 46 | { 47 | if (root == nullptr) return 0; 48 | return minDepthHelper(root); 49 | } 50 | 51 | int Solution111::minDepthHelper(TreeNode* root) 52 | { 53 | if (root->left == nullptr && root->right == nullptr) return 1; 54 | if (root->left == nullptr) return 1 + minDepthHelper(root->right); 55 | if (root->right == nullptr) return 1 + minDepthHelper(root->left); 56 | return 1 + min(minDepthHelper(root->left), minDepthHelper(root->right)); 57 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/112 - pathSum.cpp: -------------------------------------------------------------------------------- 1 | #include "112 - pathSum.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Easy 6 | Please refer to "112. Path Sum" for the problem statement. 7 | https://leetcode.com/problems/path-sum/description/ 8 | 9 | Solution: 10 | While we traverse the tree, we keep track of a running total in each direction that we go in. 11 | Whenever we reach a root node we see if the running total matches the sum. 12 | 13 | Let N be the number of nodes in the tree. 14 | Time Complexity: O(N), the final leaf that we consider might contain the path that represents the sum, even though all the others have failed. 15 | Space Complexity: O(N), consider the call stack 16 | 17 | Be Aware: 18 | -Watch out for your base cases. 19 | -This is another good example of how using a helper recursive function can make it a lot easier to solve. 20 | 21 | Tests: 22 | -Empty tree 23 | -Tree with no path sum 24 | -Tree with a path sum 25 | -Tree with root value 1, left value 2, and sum 1. This should return false, but if base case coded wrong could return true. 26 | */ 27 | 28 | 29 | /** 30 | * Definition for a binary tree node. 31 | * struct TreeNode { 32 | * int val; 33 | * TreeNode *left; 34 | * TreeNode *right; 35 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 36 | * }; 37 | */ 38 | 39 | bool Solution112::hasPathSum(TreeNode* root, int sum) 40 | { 41 | if (root == nullptr) return false; 42 | return hasPathSumHelper(root, sum, 0); 43 | } 44 | 45 | bool Solution112::hasPathSumHelper(TreeNode* root, int sum, int current) 46 | { 47 | if (root == nullptr) return false; 48 | if (root->left == nullptr && root->right == nullptr) return sum == current + root->val; 49 | 50 | return hasPathSumHelper(root->left, sum, current + root->val) || hasPathSumHelper(root->right, sum, current + root->val); 51 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/113 - pathSumII.cpp: -------------------------------------------------------------------------------- 1 | #include "113 - pathSumII.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "113. Path Sum II" for the problem statement. 9 | https://leetcode.com/problems/path-sum-ii/description/ 10 | 11 | Solution: 12 | We keep an integer vector representing a single path that we are constructing. 13 | We also pass in a reference to a vector of int vectors that will be our result. 14 | If we ever reach a leaf node and determine that the leaf is the end of a proper path, we add it to the result. 15 | 16 | Let N be the number of nodes in the tree. 17 | Time Complexity: O(N), each node must be visited to aggregate the sum value and to check if it is a leaf 18 | Space Complexity: O(NlogN). 19 | -Consider a complete tree with the bottom layer filled. If every one of these leaves is the end of a path to the target sum, then the leaves will appear once each, their parents twice each, and so on. 20 | -However, the number of nodes on levels halves each time it gets closer to the root level, so N integers will appear in the result vector for each layer, hence NlogN. 21 | -Note that in the case of a tree with one leaf the result vector can only contain one path, and if so that path will be of length N. 22 | 23 | Be Aware: 24 | -Why is it better to pass the vectors in by reference rather than by value? 25 | -This is a good example of how using a helper function in a recursive call can help make the problem a lot easier. 26 | -Don't forget to pop out the back item on your path. Otherwise you might be keeping track of an incorrect path! 27 | 28 | Tests: 29 | [5,4,8,11,null,13,4,7,2,null,null,5,1] 30 | 22 31 | 32 | Empty tree 33 | 34 | [1, 2] 35 | 1 36 | 37 | [1, 2] 38 | 3 39 | 40 | [] 41 | 0 42 | */ 43 | 44 | /** 45 | * Definition for a binary tree node. 46 | * struct TreeNode { 47 | * int val; 48 | * TreeNode *left; 49 | * TreeNode *right; 50 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 51 | * }; 52 | */ 53 | vector> Solution113::pathSum(TreeNode* root, int sum) 54 | { 55 | vector> result; 56 | vector path; 57 | if (root == nullptr) return result; 58 | pathSumHelper(root, sum, path, result); 59 | return result; 60 | } 61 | 62 | void Solution113::pathSumHelper(TreeNode* root, int sum, vector& path, vector>& result) 63 | { 64 | if (root == nullptr) return; 65 | path.push_back(root->val); 66 | if (root->left == nullptr && root->right == nullptr && root->val == sum) 67 | result.push_back(path); 68 | pathSumHelper(root->left, sum - root->val, path, result); 69 | pathSumHelper(root->right, sum - root->val, path, result); 70 | path.pop_back(); 71 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/114 - flattenBinaryTreeToLinkedList.cpp: -------------------------------------------------------------------------------- 1 | #include "114 - flattenBinaryTreeToLinkedList.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Medium 6 | Please refer to "114. Flatten Binary Tree to Linked List" for the problem statement. 7 | https://leetcode.com/problems/flatten-binary-tree-to-linked-list/description/ 8 | 9 | Solution: 10 | This problem can be solved iteratively. 11 | Initialize temp at the root. 12 | While temp isn't nullptr 13 | If it's left isn't a nullptr 14 | Save temp's current right so we don't lose it 15 | Move temp's left to temp's right. 16 | Proceed as far right as we can 17 | Reattach the saved right to the rightmost portion. 18 | Move temp to its right 19 | 20 | Let N be the number of nodes in the tree. 21 | Time Complexity: N/A (TODO) 22 | Space Complexity: O(1), iterative solution with only a few pointers initialized 23 | Be Aware: 24 | -Notice that in the problem the final form corresponds to a preorder traversal. So in essence this iterative solution is a preorder traversal + manipulations. 25 | -Every time a node has a left, we want that node to end up as the immediate right. This propagates recursively (so a recursive solution is quite easy here) 26 | -However, by our implementation the next node we consider by moving right is identically the one that we just considered in our preorder traversal, which is why it works. 27 | -rightHolder holds the right half of a subtree. It's added at the end because we know that in a preorder traversal all of the left items will be considered first. 28 | */ 29 | 30 | /** 31 | * Definition for a binary tree node. 32 | * struct TreeNode { 33 | * int val; 34 | * TreeNode *left; 35 | * TreeNode *right; 36 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 37 | * }; 38 | */ 39 | 40 | void Solution114::flatten(TreeNode* root) 41 | { 42 | if (root == nullptr) return; 43 | TreeNode *temp = root; 44 | while (temp != nullptr) 45 | { 46 | if (temp->left != nullptr) 47 | { 48 | TreeNode *rightHolder = temp->right; 49 | temp->right = temp->left; 50 | temp->left = nullptr; 51 | 52 | TreeNode *rightDiver = temp; 53 | while (rightDiver->right != nullptr) 54 | rightDiver = rightDiver->right; 55 | rightDiver->right = rightHolder; 56 | } 57 | temp = temp->right; 58 | } 59 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/121 - bestTimeToBuyAndSellStock.cpp: -------------------------------------------------------------------------------- 1 | #include "121 - bestTimeToBuyAndSellStock.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "121. Best Time to Buy and Sell Stock" for the problem statement. 9 | https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/ 10 | 11 | Solution: 12 | We initially consider the case where we buy on the first day and sell on the very next day. 13 | We can then iterate through the remaining days to eventually find the maximum profit we can make. Here's how: 14 | -Keep track of our current max profit and the lowest price encountered so far (or an index to it) 15 | -If we encounter a day with a price lower than our current lowest price, update our lowest price; any sale in the future would be better with a buy on this day than at what was tracked before. 16 | -If we encounter a day with a price higher than our current lowest price, it is a potential sell day. Compare the price difference to the current max profit, and update if necessary. 17 | 18 | Let N be the size of the input array. 19 | Time Complexity: O(N) 20 | Space Complexity: O(1) 21 | 22 | Be Aware: 23 | -There are tons of variations of this problem, ranging across all difficulties. 24 | -Don't forget that there exists a scenario where it's better to never buy! 25 | 26 | Test Cases: 27 | [1,2,3,4,5] 28 | [1] 29 | [1,2] 30 | [2,1] 31 | [2,4,1,5] 32 | */ 33 | 34 | int Solution121::maxProfit(vector& prices) 35 | { 36 | if (prices.size() < 2) return 0; 37 | 38 | int result = prices[1] - prices[0]; 39 | int buy_ind = 0; 40 | 41 | for (int i = 1; i < prices.size(); i++) 42 | { 43 | if (prices[i] < prices[buy_ind]) 44 | { 45 | buy_ind = i; 46 | } 47 | else 48 | { 49 | result = max(result, prices[i] - prices[buy_ind]); 50 | } 51 | } 52 | 53 | return max(result, 0); 54 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/122 - bestTimeToBuyAndSellStockII.cpp: -------------------------------------------------------------------------------- 1 | #include "122 - bestTimeToBuyAndSellStockII.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "122. Best Time to Buy and Sell Stock II" for the problem statement. 9 | https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/description/ 10 | 11 | Solution: 12 | Because this time there is no limit to the number of times the stock can be purchased and sold, we simply add all the days where we can make a profit by buying that day and selling the next. 13 | Situations: 14 | -Small, Large, Medium: Profit captured in Small->Large 15 | -Small, Medium, Large: Max profit is still Small->Large, however we capture this in the code with Small->Medium followed by Medium->Large 16 | -Medium, Small, Large: Ignore Medium 17 | -Medium, Large, Small: Max profit captured in Medium->Large 18 | -Large, Small, Medium: Max profit captured in Small->Medium 19 | -Large, Medium, Small: No profit can be gained 20 | 21 | Let N be the size of the input array. 22 | Time Complexity: O(N) 23 | Space Complexity: O(1) 24 | 25 | Be Aware: 26 | -This question is nontrivial, and is indeed a test of clarity as well. Depending on the wording of the problem it can be interpreted as a different problem entirely. 27 | -Refer to the Discussion page for this problem; previously the wording made it appear there were additional restrictions. 28 | */ 29 | int Solution122::maxProfit(vector& prices) 30 | { 31 | int result = 0; 32 | for (int i = 1; i < prices.size(); i++) 33 | { 34 | if (prices[i] - prices[i - 1] > 0) result += prices[i] - prices[i - 1]; 35 | } 36 | return result; 37 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/124 - binaryTreeMaximumPathSum.cpp: -------------------------------------------------------------------------------- 1 | #include "124 - binaryTreeMaximumPathSum.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Hard 8 | Please refer to "124. Binary Tree Maximum Path Sum" for the problem statement. 9 | https://leetcode.com/problems/binary-tree-maximum-path-sum/description/ 10 | 11 | Solution: 12 | This problem is difficult because it is a recursion problem where there is a ton of stuff to keep track of. 13 | For every node, we are interested in the maximum path within its tree that includes itself, going in only one direction. 14 | By returning this information, we can use it recursively to construct longer paths. 15 | We also want to keep track of the value of the maximum path itself 16 | By having this tracked by reference and used in a helper function, we free up the return value to return the information above. 17 | 18 | Given a root node, there are a variety of paths can constitute the maximum path. 19 | 1. The root node itself, with nothing else. 20 | 2. The root node as one end of the path, with the path extending into the right subtree. 21 | 3. The root node as one end of the path, with the path extending into the left subtree. 22 | 4. The root node is in the middle of the path; that is, both the left and right nodes are included in the max path. 23 | 5. The max path doesn't include this root, and is instead in the left subtree. 24 | 6. The max path doesn't include this root, and is instead in the right subtree. 25 | 26 | How do we account for all of these situations with just the things we are tracking above? 27 | 28 | For a node, if we call the helper on the left and right subtrees, we get the maximum path sums that include the left and right nodes respectively. 29 | If either of them are negative, then we don't want to include those in the maximum path sum of the node we are currently considering. 30 | 31 | This covers scenarios 1-4: 32 | 1. Both the left recursive call and the right recursive call produced negative values so including either would worsen our sum. 33 | 2. The right recursive call produced a negative value, but the left recursive call produced a positive one, so it could potentailly contribute to our sum. 34 | 3. The left recursive call produced a negatve value, but right recursive call produced a positive one, so it could potentially contribute to our sum. 35 | 4. Both the left recursive call and the right recursive calls produced positive values that could potentially contribute to our sum. 36 | 37 | How about 5-6? This is why building upwards is important. As we go up, we keep track of the largest sum compared so far. 38 | For any given recursive call C, if 1-4 doesn't beat the stored result, then the 1-4 of a recursive call originating from call C produced a better value. 39 | In fact, we find that situations 5-6 are just a fancy way of saying, some later call's 1-4 stored a larger result here than the best solution that this call's 1-4 could produce. 40 | 41 | How does this all translate to code? 42 | Our original function initializes the running max to INT_MIN and triggers the helper call that has the reference to the max, returning it after the helper call completes. 43 | The helper does the meat of the work: 44 | If nullptr then return 0: it contributes nothing to the sum 45 | Store the results of the helper call on the left and right subtrees, setting them to 0 if they are less than 0 to represent not using that max sum 46 | If the current val + max including left node + max including right node > current max, then we update the max. This statement covers the best of situations 1-4. 47 | Return the current val + max(max including left node, max including right node), which is the max including the current root 48 | 49 | Let N be the number of nodes in the tree 50 | Time Complexity: O(N), every node is visisted once, and gets its current value + max including left + max including right calculated once 51 | Space Complexity: O(N), on the recursive call stack 52 | 53 | Be Aware: 54 | -Note that this solution is very similar to Leetcode user xt2357's solution given at the following link: https://discuss.leetcode.com/topic/5508/simple-o-n-algorithm-with-one-traversal-through-the-tree 55 | -A key difference, is that his solution actually modifies the values of the nodes in the tree while the one I implemented does not perform this modification. Credit to him for the core of the algorithm; the solution here presents only a small improvement. 56 | -Note the usage of a reference to an integer to maintain a running result in the helper function, allowing the helper to return additional helpful information. 57 | -This is a bottom up recursive approach. 58 | -There are many path possibilities which makes it hard to account for each scenario individually. 59 | 60 | Tests: 61 | TODO: 62 | Ideally it would be a full, complete tree with all nodes on the last row of depth 3, one test per configuration 63 | Also, a tree with only negative values would be nice to test as an edge case. 64 | */ 65 | 66 | /** 67 | * Definition for a binary tree node. 68 | * struct TreeNode { 69 | * int val; 70 | * TreeNode *left; 71 | * TreeNode *right; 72 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 73 | * }; 74 | */ 75 | 76 | int Solution124::maxPathSum(TreeNode* root) 77 | { 78 | int max = INT_MIN; 79 | maxPathSumHelper(root, max); 80 | return max; 81 | } 82 | 83 | int Solution124::maxPathSumHelper(TreeNode* root, int& result) 84 | { 85 | if (root == nullptr) return 0; 86 | int left = maxPathSumHelper(root->left, result); 87 | int right = maxPathSumHelper(root->right, result); 88 | if (left < 0) left = 0; 89 | if (right < 0) right = 0; 90 | if (result < root->val + left + right) result = root->val + left + right; 91 | return root->val + max(left, right); 92 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/125 - validPalindrome.cpp: -------------------------------------------------------------------------------- 1 | #include "125 - validPalindrome.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "125. Valid Palindrome" for the problem statement. 9 | https://leetcode.com/problems/valid-palindrome/description/ 10 | 11 | Solution: 12 | We start an iterator at the beginning, and one at the end, and match characters for both iterators. Anytime we don't have a match we immediately return false. 13 | If they pass each other without failing, then we have ourselves a valid palindrome. 14 | Note that in this case we pass over non alphanumeric characters and perform some processing on alphanumeric characters to make case irrelevant as well, as specified by the problem. 15 | 16 | Let N be the number of characters in the string. 17 | Time Complexity: O(N) 18 | Space Complexity: O(1) 19 | 20 | Be Aware: 21 | -Don't forget that we defined an empty string to return true. 22 | -Remember to both decrement the backward iterator and increment the forward pointer if they match; each character needs to only be matched a single time. 23 | 24 | */ 25 | 26 | 27 | bool Solution125::isPalindrome(string s) 28 | { 29 | if (s.size() == 0) return true; 30 | int forward = 0; 31 | int backward = s.size() - 1; 32 | 33 | while (forward < backward) 34 | { 35 | if (!isalnum(s[forward])) 36 | { 37 | forward++; 38 | continue; 39 | } 40 | 41 | if (!isalnum(s[backward])) 42 | { 43 | backward--; 44 | continue; 45 | } 46 | 47 | if (tolower(s[forward]) != tolower(s[backward])) return false; 48 | backward--; 49 | forward++; 50 | } 51 | 52 | return true; 53 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/129 - sumRootToLeafNumbers.cpp: -------------------------------------------------------------------------------- 1 | #include "129 - sumRootToLeafNumbers.h" 2 | 3 | /* 4 | Difficulty: Medium 5 | Please refer to "129. Sum Root to Leaf Numbers" for the problem statement. 6 | https://leetcode.com/problems/sum-root-to-leaf-numbers/description/ 7 | 8 | Solution: 9 | We simply write a helper function that allows us to track the running tally down each path. As soon as we encounter a leaf node, we can return that value as a path sum. 10 | Otherwise, we take the node's current value, account for it as part of our running number, and return the sum down both the left and right. 11 | 12 | Let N be the number of nodes in the tree 13 | Time Complexity: O(N) 14 | Space Complexity: O(N) 15 | 16 | Tests: 17 | Empty Tree 18 | Tree with just a root 19 | Full and complete tree 20 | Tree with branches ending at many depths 21 | 22 | */ 23 | /** 24 | * Definition for a binary tree node. 25 | * struct TreeNode { 26 | * int val; 27 | * TreeNode *left; 28 | * TreeNode *right; 29 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 30 | * }; 31 | */ 32 | 33 | int Solution129::sumNumbers(TreeNode* root) 34 | { 35 | return sumNumbersHelper(root, 0); 36 | } 37 | 38 | int Solution129::sumNumbersHelper(TreeNode* root, int path) 39 | { 40 | if (root == nullptr) return 0; 41 | int new_path = path * 10 + root->val; 42 | if (root->left == nullptr && root->right == nullptr) return new_path; 43 | return sumNumbersHelper(root->left, new_path) + sumNumbersHelper(root->right, new_path); 44 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/136 - singleNumber.cpp: -------------------------------------------------------------------------------- 1 | #include "136 - singleNumber.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "136. Single Number" for the problem statement. 9 | https://leetcode.com/problems/single-number/description/ 10 | 11 | Solution: 12 | There are many ways to solve this problem, which may be added later on as alternate solutions. 13 | This particular solution leverages the fact that taking two of the same number and performing an XOR operation results in a 0. 14 | Given the input that we have, all you need to do is loop through once and XOR everything, then return that, since the singleton won't have something to cancel it. 15 | 16 | Let N be the size of the input array. 17 | Time Complexity: O(N) 18 | Space Complexity: O(1) 19 | 20 | Be Aware: 21 | -What are some other, more conventional ways to solve the problem? 22 | -What are the time complexities of such solutions? 23 | 24 | Tests: 25 | -Array with just a singleton 26 | -Empty array 27 | -Any array with a random singleton in a random spot and a bunch of random number pairings 28 | */ 29 | 30 | int Solution136::singleNumber(vector& nums) 31 | { 32 | int result = 0; 33 | for (int i = 0; i < nums.size(); i++) 34 | { 35 | result ^= nums[i]; 36 | } 37 | 38 | return result; 39 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/137 - singleNumberII.cpp: -------------------------------------------------------------------------------- 1 | #include "137 - singleNumberII.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "137. Single Number II" for the problem statement. 9 | https://leetcode.com/problems/single-number-ii/description/ 10 | 11 | Solution: 12 | There are many ways to solve this problem, including: 13 | -Brute force, O(N^2) 14 | -Hash table appearance counter, O(N) time, O(N) space 15 | -Determine whatever equivalent operation as the XOR to find the singleton in O(N). 16 | This solution solves the problem in O(N) time using constant memory. Credit to Prathyush Katukojwala for coming up with the idea for this!! 17 | 18 | The XOR trick in 136 no longer works, since 3x and 1x are both odds, so XORs cannot cancel copies out nicely. 19 | We can instead count the number of times each bit is set for each of the 32 bits in an int, and mod that by 3 to get 1 in all the places where the bit is set 20 | in the correct answer. 21 | 22 | Be Aware: 23 | -Don't mix math operations and bit operations if you can help it. It can produce weird interactions when dealing with negative numbers. 24 | -The integer in this solution is a 32 bit value where the bit at the kth (starting from 0) represents 2^k. The most significant bit is negative to allow 25 | for negative number representations. 26 | 27 | Tests: 28 | -Array with just one number 29 | -Array with negative singleton, various triplets 30 | -Array with positive singleton, various triplets 31 | -Array with only negative numbers 32 | -Array with only positive numbers 33 | */ 34 | int Solution137::singleNumber(vector& nums) 35 | { 36 | vector resultBits(sizeof(int) * 8, 0); 37 | for (int i = 0; i < nums.size(); i++) 38 | { 39 | int current = nums[i]; 40 | for (int j = 0; j < sizeof(int) * 8; j++) 41 | { 42 | resultBits[j] += current & 1; 43 | current >>= 1; 44 | } 45 | } 46 | 47 | int result = 0; 48 | for (int k = 0; k < resultBits.size(); k++) 49 | result |= ((resultBits[k] % 3) << k); 50 | return result; 51 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/141 - linkedListCycle.cpp: -------------------------------------------------------------------------------- 1 | #include "141 - linkedListCycle.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Easy 6 | Please refer to "141. Linked List Cycle" for the problem statement. 7 | https://leetcode.com/problems/linked-list-cycle/description/ 8 | 9 | Solution: 10 | We have a slow "tortoise" pointer that jumps one at a time. 11 | We also have a fast "hare" pointer that jumps two at a time. 12 | After they both jump away from the start, if there is a cycle the hare will catch the tortoise. 13 | Otherwise the hare will eventually reach the end and there will be no cycle. 14 | 15 | Be Aware: 16 | -Watch out for null pointer access, especially with the hare. 17 | -Don't accidentally check to see if they're the same spot at the start and have that be the cycle. 18 | Test Cases: 19 | -Empty list 20 | -List with no cycle 21 | -List with a cycle of 3, with the 2nd node as the entry point. 22 | -List with a cycle of 4, with the 2nd node as the entry point. 23 | -List with a cycle of 5, with the 2nd node as the entry point. 24 | -List with a cycle of 3, with the 3rd node as the entry point. 25 | -List with a cycle of 4, with the 3rd node as the entry point. 26 | -List with a cycle of 5, with the 3rd node as the entry point. 27 | -List with a node that points back to itself as a cycle. 28 | */ 29 | 30 | /** 31 | * Definition for singly-linked list. 32 | * struct ListNode { 33 | * int val; 34 | * ListNode *next; 35 | * ListNode(int x) : val(x), next(NULL) {} 36 | * }; 37 | */ 38 | 39 | bool Solution141::hasCycle(ListNode *head) 40 | { 41 | ListNode *tortoise = head; 42 | ListNode *hare = head; 43 | 44 | while (hare != nullptr) 45 | { 46 | tortoise = tortoise->next; 47 | hare = hare->next; 48 | if (hare == nullptr) return false; 49 | hare = hare->next; 50 | if (hare == tortoise) return true; 51 | } 52 | 53 | return false; 54 | } 55 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/142 - linkedListCycleII.cpp: -------------------------------------------------------------------------------- 1 | #include "142 - linkedListCycleII.h" 2 | 3 | /* 4 | Difficulty: Medium 5 | Please refer to "142. LinkedListCycle II" for the problem statement. 6 | https://leetcode.com/problems/linked-list-cycle-ii/description/ 7 | 8 | Solution: 9 | Credit to LeetCode user ngcl for this detailed algorithm explanation! 10 | Check it out here: https://discuss.leetcode.com/topic/5284/concise-o-n-solution-by-using-c-with-detailed-alogrithm-description 11 | 12 | We have a tortoise pointer that advances one node at a time. 13 | We have a hare pointer that advances two nodes at a time. 14 | If there exists a cycle, the hare will eventually catch up to the tortoise. 15 | At this point, the forward distance from the meeting point will be the same as the distance from the head to the meeting point. 16 | 17 | Proof: 18 | Let L1 be the distance from the head to the entry point of the cycle. 19 | Let L2 be the distance between the entry point and the meeting point (where the tortoise and hare next meet). 20 | Let C be the length of the cycle. 21 | Let n be the number of times the hare has traveled around the cycle when it meets the tortoise. 22 | 23 | When the two meet... 24 | The tortoise has traveled L1 + L2 nodes. 25 | The hare has traveled L1 + L2 + n * C nodes. 26 | 27 | Because the hare has traveled twice as far as the tortoise, we have... 28 | 2 (L1 + L2) = L1 + L2 + n * C 29 | L1 + L2 = n * C 30 | L1 = (n - 1) * C + (C - L2) 31 | 32 | We realize that (n - 1) * C is just some number of whole cycle traversals, and that 33 | C - L2 is the remaining forward distance that you need to travel from the meeting point to return to the entry point. 34 | 35 | Because of this realization, if the tortoise and hare meet, we can just advance the tortoise and a pointer beginning at head until they are at the same spot. 36 | That spot will be the entry point of the cycle! 37 | 38 | Be aware: 39 | -Watch out for nullptr access, especially when considering the hare. 40 | -In a real interview, you might not necessarily see this mathematical property immediately. It's important to try test cases and see if you can find a pattern. 41 | 42 | Tests: 43 | -Empty list 44 | -List with no cycle. 45 | -List with the 2nd node as the entry point, cycle of size 3. 46 | -List with the 2nd node as the entry point, cycle of size 4. 47 | -List with the 2nd node as the entry point, cycle of size 5. 48 | -List with the 3rd node as the entry point, cycle of size 3. 49 | -List with the 3rd node as the entry point, cycle of size 4. 50 | -...... 51 | */ 52 | /** 53 | * Definition for singly-linked list. 54 | * struct ListNode { 55 | * int val; 56 | * ListNode *next; 57 | * ListNode(int x) : val(x), next(NULL) {} 58 | * }; 59 | */ 60 | 61 | ListNode* Solution142::detectCycle(ListNode *head) 62 | { 63 | ListNode *tortoise = head; 64 | ListNode *hare = head; 65 | 66 | while (hare != nullptr) 67 | { 68 | tortoise = tortoise->next; 69 | hare = hare->next; 70 | if (hare == nullptr) return nullptr; 71 | hare = hare->next; 72 | if (hare == tortoise) 73 | { 74 | ListNode *temp = head; 75 | while (temp != tortoise) 76 | { 77 | tortoise = tortoise->next; 78 | temp = temp->next; 79 | } 80 | return temp; 81 | } 82 | } 83 | 84 | return nullptr; 85 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/143 - reorderList.cpp: -------------------------------------------------------------------------------- 1 | #include "143 - reorderList.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Medium 6 | Please refer to "143. Reorder List" for the problem statement. 7 | https://leetcode.com/problems/reorder-list/description/ 8 | 9 | Solution: 10 | Iterate halfway through the list, reverse the second half, and then perform an alternating merge. 11 | 12 | Time Complexity: O(N) 13 | Space Complexity: O(1) 14 | 15 | Be Aware: 16 | -Watch out for special cases. 17 | -Notice the use of a faster and slower moving pointer to find the halfway point of a linked list. 18 | */ 19 | /** 20 | * Definition for singly-linked list. 21 | * struct ListNode { 22 | * int val; 23 | * ListNode *next; 24 | * ListNode(int x) : val(x), next(NULL) {} 25 | * }; 26 | */ 27 | void Solution143::reorderList(ListNode* head) 28 | { 29 | if (head == nullptr || head->next == nullptr) return; 30 | 31 | ListNode *tortoise = head; 32 | ListNode *hare = head; 33 | 34 | while (hare != nullptr) 35 | { 36 | tortoise = tortoise->next; 37 | hare = hare->next; 38 | if (hare != nullptr) hare = hare->next; 39 | } 40 | 41 | ListNode *temp = head; 42 | while (temp->next != tortoise) temp = temp->next; 43 | temp->next = nullptr; 44 | 45 | //Tortoise is now pointing at the start of the LL from which we want to reverse. 46 | ListNode *prev = nullptr; 47 | ListNode *next = tortoise->next; 48 | 49 | while (next != nullptr) 50 | { 51 | tortoise->next = prev; 52 | prev = tortoise; 53 | tortoise = next; 54 | next = tortoise->next; 55 | } 56 | tortoise->next = prev; 57 | 58 | //Prev now pointing at the start of the reversed LL 59 | ListNode *L1 = head; 60 | ListNode *L2 = tortoise; 61 | 62 | while (L1 != nullptr && L2 != nullptr) 63 | { 64 | ListNode *temp1 = L1->next; 65 | L1->next = L2; 66 | ListNode *temp2 = L2->next; 67 | L2->next = temp1; 68 | L1 = temp1; 69 | L2 = temp2; 70 | } 71 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/144 - binaryTreePreorderTraversal.cpp: -------------------------------------------------------------------------------- 1 | #include "144 - binaryTreePreorderTraversal.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "144. Binary Tree Preorder Traversal" for the problem statement. 9 | https://leetcode.com/problems/binary-tree-preorder-traversal/description/ 10 | 11 | Solution: 12 | To perform a preorder traversal iteratively, we use a stack, that only contains non-nullptr TreeNode pointers. 13 | If the root is pointing at an actual TreeNode, we add it to the stack. 14 | Then, so long as the stack isn't empty, we take the value stored in the node at the top of the stack and append it to our result. 15 | Then, we pop the processed node up, then push its right child if it is not nullptr, then its left child if it is not nullptr. 16 | This ensures that we will process a node, then its left child, then its right child, just like in a preorder traversal. 17 | 18 | Let N be the number of nodes in the tree. 19 | Time Complexity: O(N), a traversal 20 | Space Complexity: O(N), the stack will contain N/2 nodes at some point for a full, complete binary tree. 21 | 22 | Be Aware: 23 | -How might this solution be adapted to use 24 | -What would be a recursive method of doing this? How about the space complexity of that? 25 | 26 | Tests: 27 | Empty tree 28 | Tree with one node 29 | Full, complete tree with depth 5 30 | Tree with many branches that terminate at different depths 31 | */ 32 | 33 | /** 34 | * Definition for a binary tree node. 35 | * struct TreeNode { 36 | * int val; 37 | * TreeNode *left; 38 | * TreeNode *right; 39 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 40 | * }; 41 | */ 42 | 43 | vector Solution144::preorderTraversal(TreeNode* root) 44 | { 45 | if (root == nullptr) return vector(); 46 | 47 | vector result; 48 | 49 | stack stk; 50 | stk.push(root); 51 | while (!stk.empty()) 52 | { 53 | TreeNode* temp = stk.top(); 54 | result.push_back(temp->val); 55 | stk.pop(); 56 | if (temp->right != nullptr) stk.push(temp->right); 57 | if (temp->left != nullptr) stk.push(temp->left); 58 | } 59 | 60 | return result; 61 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/145 - binaryTreePostOrderTraversal.cpp: -------------------------------------------------------------------------------- 1 | #include "145 - binaryTreePostorderTraversal.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Hard 8 | Please refer to "145. Binary Tree Postorder Traversal" for the problem statement. 9 | https://leetcode.com/problems/binary-tree-postorder-traversal/description/ 10 | 11 | Solution: 12 | We initialize a stack, and push the root onto it if it isn't nullptr. 13 | Then we continue to take the top item of the stack, push left if not nullptr, and push right if not nullptr, and adding the top item to the result. 14 | At the end, we reverse the entire result to change it from a preorder traversal to a postorder traversal. 15 | 16 | Essentially, before reversal we have: 17 | Process current 18 | Process right 19 | Process left 20 | Which becomes... 21 | Process left 22 | Process right 23 | Process current 24 | 25 | Let N be the number of nodes in the tree 26 | Time Complexity: O(N) 27 | Space Complexity: O(N) 28 | 29 | Tests: 30 | Empty tree 31 | Full, complete tree of depth 5 32 | Sparse tree with branches that end at various depths 33 | */ 34 | 35 | /** 36 | * Definition for a binary tree node. 37 | * struct TreeNode { 38 | * int val; 39 | * TreeNode *left; 40 | * TreeNode *right; 41 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 42 | * }; 43 | */ 44 | 45 | vector Solution145::postorderTraversal(TreeNode* root) 46 | { 47 | if (root == nullptr) return vector(); 48 | vector result; 49 | stack stk; 50 | stk.push(root); 51 | while (!stk.empty()) 52 | { 53 | TreeNode* temp = stk.top(); 54 | stk.pop(); 55 | if (temp->left != nullptr) stk.push(temp->left); 56 | if (temp->right != nullptr) stk.push(temp->right); 57 | result.push_back(temp->val); 58 | } 59 | 60 | reverse(result.begin(), result.end()); 61 | return result; 62 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/153 - findMinimumInRotatedSortedArray.cpp: -------------------------------------------------------------------------------- 1 | #include "153 - findMinimumInRotatedSortedArray.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "153. Find Minimum in Rotated Sorted Array" for the problem statement. 9 | https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/description/ 10 | 11 | Solution: 12 | Initially we check to make sure that there in fact is a rotation. 13 | If so, we begin looping through and finding the value stored at the midpoint. 14 | If the midpoint's value is greater than the leftmost value, then we haven't passed the rotation point yet and we eliminate the left half. 15 | If the midpoint's value is less than the leftmost value, then we already passed the rotation point and we eliminate the right half. 16 | We continue onwards until we have narrowed our search to 1 location. 17 | 18 | Time Complexity: O(logN) 19 | Space Complexity: O(1), performed iteratively with no additional data structures. 20 | 21 | Be Aware: 22 | -There is a recurisve solution to this problem. Why might a recursive solution not be as good as this one, in terms of space complexity? 23 | 24 | Tests: 25 | [] 26 | [1] 27 | [1,2,3,4,5,6] 28 | [3,4,5,6,7,8,1,2] 29 | [3,4,5,6,7,1,2] 30 | */ 31 | 32 | int Solution153::findMin(vector& nums) 33 | { 34 | int low = 0; 35 | int high = nums.size() - 1; 36 | if (nums[low] < nums[high]) return nums[low]; 37 | while (low < high) 38 | { 39 | int mid = low + (high - low) / 2; 40 | if (nums[mid] > nums[high]) low = mid + 1; 41 | else high = mid; 42 | } 43 | 44 | return nums[low]; 45 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/155 - minStack.cpp: -------------------------------------------------------------------------------- 1 | #include "155 - minStack.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "155. Min Stack" for the problem statement. 9 | https://leetcode.com/problems/min-stack/description/ 10 | 11 | Solution: 12 | We have two stacks; one to represent the contents of the minstack and another to represent a history of minimums in the stack. 13 | They will be called stk and mins, respectively. 14 | 15 | Mins will always have the minstack's minimum item at the top. 16 | 17 | push() - If mins is empty then whatever we add to stk should also be added to mins. Otherwise we only add to mins if the item is smaller than the current minimum at the top of the stack. 18 | pop() - Comare the item to be popped in stk with the item at the top of mins. If they match then the top of mins was added to mins when the item about to be popped off stk was added, so we should also pop off of mins (whew). 19 | top() - No change in functionality from a normal stack! 20 | getMin() - Corresponds to the most recent minimum in our history, which is identically the top of mins like we hoped. 21 | 22 | Be Aware: 23 | -I modified the class declaration from MinStack to Solution155 to preserve the class numbering precedent I have set in the rest of the repository. 24 | -Credit to UCLA student Ying Bin Wu for providing the strategy for this solution!! 25 | */ 26 | 27 | /** 28 | * Your MinStack object will be instantiated and called as such: 29 | * Solution155 obj = new MinStack(); 30 | * obj.push(x); 31 | * obj.pop(); 32 | * int param_3 = obj.top(); 33 | * int param_4 = obj.getMin(); 34 | */ 35 | 36 | void Solution155::push(int x) 37 | { 38 | if (mins.empty() || x <= mins.top()) 39 | { 40 | mins.push(x); 41 | } 42 | stk.push(x); 43 | } 44 | 45 | void Solution155::pop() 46 | { 47 | if (!stk.empty() && !mins.empty() && stk.top() == mins.top()) mins.pop(); 48 | stk.pop(); 49 | } 50 | 51 | int Solution155::top() 52 | { 53 | return stk.top(); 54 | } 55 | 56 | int Solution155::getMin() 57 | { 58 | return mins.top(); 59 | } 60 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/162 - findPeakElement.cpp: -------------------------------------------------------------------------------- 1 | #include "162 - findPeakElement.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "162. Find Peak Element" for the problem statement. 9 | https://leetcode.com/problems/find-peak-element/description/ 10 | 11 | Solution: 12 | This is a binary search problem. 13 | The key is to realize that given that the left and right bounds are negative infinity and mid, there must exist a peak and that peak can be found in one of the halves. 14 | 15 | In the search: 16 | First, we check the element at mid against its left and right to see if we have found a peak. If so, we can return right away. 17 | Otherwise, we know for sure that either the left or the right element was larger. 18 | A peak MUST exist on the side with the larger element, because there already exists a value with a smaller value on either side. 19 | 20 | One might be tempted to immediately try the larger value to check if it is a peak, but it actually makes the solution more complicated and less efficient. 21 | 22 | If we consistently use this methodology, each time we are halving the range that we know that a peak must exist, effectively creating our log(N) solution. 23 | 24 | Time Complexity: O(logN) 25 | Space Complexity: O(1) 26 | 27 | Be Aware: 28 | -Note that in this case we don't need to find the global peak. Any peak that follows the definition will do, and there can be many of them in the input data. 29 | 30 | Tests: 31 | [1, 3, 1, 4, 2] 32 | [1] 33 | [-1] 34 | [-3, -1, -2] 35 | [0, 1, 2] 36 | [2, 1, 0] 37 | [1, 3, 2, 4, 5, 6, 7, 9, 8] 38 | */ 39 | 40 | int Solution162::findPeakElement(vector& nums) 41 | { 42 | if (nums.size() == 1) return 0; 43 | if (nums.size() == 2) return nums[0] > nums[1] ? 0 : 1; 44 | int low = 0; 45 | int high = nums.size() - 1; 46 | int mid; 47 | 48 | while (low <= high) 49 | { 50 | mid = low + (high - low) / 2; 51 | if (mid == 0 && nums[mid + 1] < nums[mid]) return mid; 52 | else if (mid == nums.size() - 1 && nums[mid - 1] < nums[mid]) return mid; 53 | else if (nums[mid - 1] < nums[mid] && nums[mid + 1] < nums[mid]) return mid; 54 | else if (nums[mid - 1] > nums[mid]) high = mid - 1; 55 | else low = mid + 1; 56 | } 57 | return mid; 58 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/169 - majorityElement.cpp: -------------------------------------------------------------------------------- 1 | #include "169 - majorityElement.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "169. Majority Element" for the problem statement. 9 | https://leetcode.com/problems/majority-element/description/ 10 | 11 | Solution: 12 | Since we know there is a majority element, we can match each appearance of such an element with one that is not and cancel them out. 13 | Even after all non-majority elements are cancelled we will still have some majority elements left. 14 | Thus, we just keep track of what our current candidate for the majority element is and a count. 15 | Each time we encounter another instance, we increment the count. 16 | Each time we encounter an instance we aren't tracking, we decrement the count. 17 | If at any point the count is 1 and we need to decrement, we simply swap the candidate with the number we just encountered that caused the decrement. 18 | 19 | Time Complexity: O(N), where N is the size of the input vector 20 | Space Complexity: O(1), only requires two integers 21 | 22 | Be Aware: 23 | -Note that swapping the number we consider is the equivalent of two non-matching numbers "cancelling" each other out 24 | -Keep in mind the problem states that the input is not empty 25 | 26 | Test Cases: 27 | [1,1,1] 28 | [1,1,2] 29 | [1] 30 | [1,1,2,2,3,3,4,4,1] 31 | */ 32 | 33 | 34 | int Solution169::majorityElement(vector& nums) 35 | { 36 | int current = nums[0]; 37 | int count = 1; 38 | 39 | for (int i = 1; i < nums.size(); i++) 40 | { 41 | if (nums[i] == current) count++; 42 | else 43 | { 44 | if (count == 1) 45 | current = nums[i]; 46 | else 47 | count--; 48 | } 49 | } 50 | 51 | return current; 52 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/172 - factorialTrailingZeroes.cpp: -------------------------------------------------------------------------------- 1 | #include "172 - factorialTrailingZeroes.h" 2 | 3 | /* 4 | Difficulty: Easy 5 | Please refer to "172. Factorial Trailing Zeroes" for the problem statement. 6 | https://leetcode.com/problems/factorial-trailing-zeroes/description/ 7 | 8 | Solution: 9 | Recall that n! is simply n * n - 1 * n - 2 ... * 1 10 | Also, mathematically, every time we have an additional trailing zero we have effectively multiplied what we have by a factor of 10. 11 | Importantly, in factorials 5 will appear less often than 2, and since 2 * 5 is 10 we can count the number of trailing zeroes by counting the number of times we multiplied by 5. 12 | 13 | For each number in the range, we need to consider not only whether it contributes a 5, but how many. 14 | This can be done by dividing n by successive powers of 5. 15 | 16 | n/5 gets the number of numbers divisible by 5. 17 | n/25 gets the number of numbers divisible by 25. Note that the ones that are only divisible by 1 5 are not counted, and the ones that are divisible by 2 or more 5's are counted a second time. 18 | n/625 gets the numbe rof numbers divisible by 625. Note that the ones that are only divisible by 2 5's are not counted, and the ones that are divisible by 3 or more 5's are counted a third time. 19 | And so on... 20 | 21 | We keep doing this until n/5^i is 0, since that means that 5^i > n and there are no additional 5's left to count. 22 | 23 | Time Complexity: O(1) 24 | Space Complexity: O(1) 25 | 26 | Be Aware: 27 | -You can cheese this problem by leveraging the constraints of representing n to get an O(1) solution. This doesn't translate to other situations, however. 28 | -Also note that this solution is also technically O(1), since the representation of the inputs limits how far the while loop can go. 29 | -Note that in this instance i is a long. This is to avoid overflow from repeatedly multiplying i by 5. 30 | 31 | Tests: 32 | INT_MAX 33 | 1 34 | 5 35 | 10 36 | 247 37 | */ 38 | 39 | int Solution172::trailingZeroes(int n) 40 | { 41 | int result = 0; 42 | long i = 5; 43 | while (n / i) 44 | { 45 | result += n / i; 46 | i *= 5; 47 | } 48 | 49 | return result; 50 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/191 - numberOfOneBits.cpp: -------------------------------------------------------------------------------- 1 | #include "191 - numberOfOneBits.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Easy 6 | Please refer to "191. Number of 1 Bits" for the problem statement. 7 | https://leetcode.com/problems/number-of-1-bits/description/ 8 | 9 | Solution: 10 | So long as our input is nonzero, we know that there is still a 1 bit to be counted, so we continually check the least significant bit and rightshift it away, maintaining a count of 1's that we encounter. 11 | 12 | Time Complexity: O(1), while loop only goes for as many iterations as bits in the input 13 | Space Complexity: O(1) 14 | 15 | Be Aware: 16 | -This is a simple way to refresh on bitshifting if you are rusty. 17 | Tests: 18 | 0 19 | INTMAX 20 | 11 21 | 2^5 22 | 2^5 - 1 23 | 2^5 - 1 + 2^20 24 | */ 25 | 26 | int Solution191::hammingWeight(uint32_t n) 27 | { 28 | int result = 0; 29 | while (n > 0) 30 | { 31 | if (n & 1 == 1) result++; 32 | n >>= 1; 33 | } 34 | return result; 35 | } 36 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/198 - houseRobber.cpp: -------------------------------------------------------------------------------- 1 | #include "198 - houseRobber.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "198. House Robber" for the problem statement. 9 | https://leetcode.com/problems/house-robber/description/ 10 | 11 | Solution: 12 | -Dynamic Programming 13 | -For a given house k, the best answer is either: 14 | -loot at house k + max money robbed excluding previous house 15 | -max of money robbed including previous house or money robbed including previous house 16 | Hence, the solution is to keep a temp variable that holds the previous "include", then continually update them until you reach house N at the end. 17 | The best value will either be include or exclude! 18 | -Time Complexity: O(N) 19 | -Space Complexity: O(1) 20 | Be aware: 21 | -This question, despite an Easy tag, requires some knowledge of Dynamic Programming. It's also a reasonably tricky one to understand. 22 | -Make sure that you correctly translate your recurrence to code! 23 | Tests: 24 | [] 25 | [1] 26 | [1,2] 27 | [2,1] 28 | [2,1,1,2] 29 | */ 30 | int Solution198::rob(vector& nums) 31 | { 32 | int include = 0; 33 | int exclude = 0; 34 | int temp; 35 | for (int i = 0; i < nums.size(); i++) 36 | { 37 | temp = i; 38 | include = nums[i] + exclude; 39 | exclude = max(temp, exclude); 40 | } 41 | 42 | return max(include, exclude); 43 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/200 - numberOfIslands.cpp: -------------------------------------------------------------------------------- 1 | #include "200 - numberOfIslands.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "200. Number of Islands" for the problem statement. 9 | https://leetcode.com/problems/number-of-islands/description/ 10 | 11 | Solution: 12 | Iterate through the grid. Every time we encounter a 1, we increment our island counter, then BFS outwards to mark all other 1's in this island as 0, so we don't double count. 13 | 14 | Let N be the number of characters in the grid. 15 | Time Complexity: O(N). Each index can only be marked by the BFS one time, since after it is marked it will never be input to the function again. Each index is visited one time by the main double for loop. 16 | */ 17 | 18 | int Solution200::numIslands(vector>& grid) 19 | { 20 | int result = 0; 21 | if (grid.size() == 0) return 0; 22 | if (grid[0].size() == 0) return 0; 23 | 24 | for (int i = 0; i < grid.size(); i++) 25 | { 26 | for (int j = 0; j < grid[0].size(); j++) 27 | { 28 | if (grid[i][j] == '1') 29 | { 30 | result++; 31 | markByBFS(grid, i, j); 32 | } 33 | } 34 | } 35 | 36 | return result; 37 | } 38 | 39 | void Solution200::markByBFS(vector>& grid, int x, int y) 40 | { 41 | grid[x][y] = '0'; 42 | if (x > 0 && grid[x - 1][y] == '1') markByBFS(grid, x - 1, y); 43 | if (x < grid.size() - 1 && grid[x + 1][y] == '1') markByBFS(grid, x + 1, y); 44 | if (y > 0 && grid[x][y - 1] == '1') markByBFS(grid, x, y - 1); 45 | if (y < grid[0].size() - 1 && grid[x][y + 1] == '1') markByBFS(grid, x, y + 1); 46 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/202 - happyNumber.cpp: -------------------------------------------------------------------------------- 1 | #include "202 - happyNumber.h" 2 | 3 | 4 | /* 5 | Difficulty: Easy 6 | Please refer to "202. Happy Number" for the problem statement. 7 | https://leetcode.com/problems/happy-number/description/ 8 | 9 | Solution: 10 | We write a function to perform the digit sum square, then have a loop that has one that goes through the motions twice as fast as the other. 11 | If there is a loop that doesn't contain 1, then at some point after the starting point they will match again. 12 | Otherwise, once one of them hits 1, the other definitely will since 1 will keep producing itself. 13 | 14 | Time Complexity: TODO, however it will depend on math on the input. 15 | Space Complexity: O(1) 16 | 17 | Tests: 18 | 1 19 | 19 20 | 297 21 | 4 22 | */ 23 | 24 | 25 | bool Solution202::isHappy(int n) 26 | { 27 | int slow = n; 28 | int fast = n; 29 | do 30 | { 31 | slow = digitSumSquare(slow); 32 | fast = digitSumSquare(fast); 33 | fast = digitSumSquare(fast); 34 | } while (slow != fast); 35 | if (slow == 1) return true; 36 | return false; 37 | } 38 | 39 | int Solution202::digitSumSquare(int n) 40 | { 41 | int sum = 0; 42 | while (n > 0) 43 | { 44 | int remainder = n % 10; 45 | sum += remainder * remainder; 46 | n /= 10; 47 | } 48 | return sum; 49 | } 50 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/206 - reverseLinkedList.cpp: -------------------------------------------------------------------------------- 1 | #include "206 - reverseLinkedList.h" 2 | 3 | /* 4 | Difficulty: Easy 5 | Please refer to "206. Reverse Linked List" for the problem statement. 6 | https://leetcode.com/problems/reverse-linked-list/description/ 7 | 8 | Solution: 9 | Initialize 10 | prev to nullptr 11 | cur to head 12 | next to cur->next (if cur is not nullptr) 13 | 14 | After every iteration of the loop, you want cur->next to become prev, and then move on to the original cur->next to repeat the same process. 15 | 16 | Let N be the number of nodes in the input linked list. 17 | Time Complexity: O(N) 18 | Space Complexity: O(1) 19 | 20 | Be Aware: 21 | -This is a nice simple problem that is likely to appear as a short question on a data structures midterm. 22 | -Remember to check that a pointer is pointing to an existing object before trying to access any of that object's values. 23 | */ 24 | 25 | /** 26 | * Definition for singly-linked list. 27 | * struct ListNode { 28 | * int val; 29 | * ListNode *next; 30 | * ListNode(int x) : val(x), next(NULL) {} 31 | * }; 32 | */ 33 | 34 | ListNode* Solution206::reverseList(ListNode* head) 35 | { 36 | ListNode *prev = nullptr; 37 | ListNode *cur = head; 38 | ListNode *next; 39 | 40 | while (cur != nullptr) 41 | { 42 | next = cur->next; 43 | cur->next = prev; 44 | prev = cur; 45 | cur = next; 46 | } 47 | 48 | return prev; 49 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/215 - kthLargestElementInAnArray.cpp: -------------------------------------------------------------------------------- 1 | #include "215 - kthLargestElementInAnArray.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "215. Kth Largest Element in an Array" for the problem statement. 9 | https://leetcode.com/problems/kth-largest-element-in-an-array/description/ 10 | 11 | Solution: 12 | Transform the underlying array into a maxheap, then pop off items until the top contains the kth item. Maxheaps provide easy access to the maximum item as well as quick updates for when items are removed. 13 | 14 | Time Complexity: TODO 15 | Space Complexity: TODO 16 | 17 | Be Aware: 18 | -Always be mindful of costs when using STLs. 19 | 20 | Alternate Solutions: 21 | https://discuss.leetcode.com/topic/15256/4-c-solutions-using-partition-max-heap-priority_queue-and-multiset-respectively 22 | Major credit to LeetCode user jianchao.li.fighter for having such an excellent write up with 4 solutions, including the one I came up with! 23 | 24 | Tests: 25 | [1], 1 26 | [1,2], 1 27 | [2,1], 1 28 | [2,1], 2 29 | [1,7,2,3,6], 4 30 | */ 31 | 32 | int Solution215::findKthLargest(vector& nums, int k) 33 | { 34 | priority_queue pq(nums.begin(), nums.end()); 35 | for (int i = 1; i < k; i++) 36 | { 37 | pq.pop(); 38 | } 39 | 40 | return pq.top(); 41 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/217 - containsDuplicate.cpp: -------------------------------------------------------------------------------- 1 | #include "217 - containsDuplicate.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "217. Contains Duplicate" for the problem statement. 9 | https://leetcode.com/problems/contains-duplicate/description/ 10 | 11 | Solution: 12 | We initialize a set and begin iterating through the array of numbers. 13 | As we encounter values, we check if the set already holds the value. If so then we return true since we have just found a duplicate! 14 | Otherwise, we add the value to the set so that the set will catch future occurrences of this value. 15 | If we reach the end of the array without returning true that means every array entry had a distinct value, so we should return false. 16 | 17 | Time Complexity: O(N), where N is the size of the array 18 | Space Complexity: O(N), where N is the size of the array (in a situation where we reach the end of the for loop, the set will contain every item in nums, which were all distinct) 19 | 20 | Be Aware: 21 | -Recall that a set in the STL doesn't contain duplicates 22 | 23 | Tests: 24 | [] 25 | [1] 26 | [1,1] 27 | [1,2,2,3] 28 | [2,1,3,6,5,4,7] 29 | [2,1,3,8,5,1,7] 30 | */ 31 | 32 | bool Solution217::containsDuplicate(vector& nums) 33 | { 34 | set encountered; 35 | for (int i = 0; i < nums.size(); i++) 36 | { 37 | if (encountered.find(nums[i]) != encountered.end()) 38 | { 39 | return true; 40 | } 41 | encountered.insert(nums[i]); 42 | } 43 | return false; 44 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/226 - invertBinaryTree.cpp: -------------------------------------------------------------------------------- 1 | #include "226 - invertBinaryTree.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Easy 6 | Please refer to "226. Invert Binary Tree" for the problem statement. 7 | https://leetcode.com/problems/invert-binary-tree/description/ 8 | 9 | Solution: 10 | The key is to observe how an inverted binary tree looks like and realize that you can achieve inversion by switching each node's left and right pointers 11 | Time Complexity: O(N), where N is the number of nodes in the tree. 12 | Tests: 13 | Empty Tree 14 | Tree with one node 15 | Binary tree of depth 3 16 | */ 17 | /** 18 | * Definition for a binary tree node. 19 | * struct TreeNode { 20 | * int val; 21 | * TreeNode *left; 22 | * TreeNode *right; 23 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 24 | * }; 25 | */ 26 | 27 | 28 | TreeNode* Solution226::invertTree(TreeNode* root) 29 | { 30 | if (root == nullptr) return nullptr; 31 | TreeNode *temp = root->left; 32 | root->left = root->right; 33 | root->right = temp; 34 | invertTree(root->left); 35 | invertTree(root->right); 36 | return root; 37 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/234 - palindromeLinkedList.cpp: -------------------------------------------------------------------------------- 1 | #include "234 - palindromeLinkedList.h" 2 | 3 | /* 4 | Difficulty: Easy 5 | Please refer to "234. Palindrome Linked List" for the problem statement. 6 | https://leetcode.com/problems/palindrome-linked-list/description/ 7 | Please refer to "206. Reverse Linked List" for more information on the reverseList function 8 | 9 | Solution: 10 | Find the beginning of the second half by having a scout pointer that iterates twice as fast as another pointer, which will point at the second half once the scout reaches the end of the LL. 11 | Reverse that half 12 | Now, beginning from the start and the half, iterate through both and compare values, returning false if the values fail to match. 13 | If we make it through both halves then we return true 14 | 15 | Time Complexity: O(N) 16 | Space Complexity: O(1) 17 | 18 | Be Aware: 19 | -This solution performs modifications on the list, then undoes them before returning. Is there a solution that eliminates the need to do this? 20 | -Make sure to consider the case where the linked list is of odd length 21 | 22 | Tests: 23 | Empty list 24 | 1 25 | 1->1 26 | 1->2->1 27 | 1->2->2->1 28 | 1->2->3->4->5 29 | 1->2->3->4 30 | */ 31 | 32 | /** 33 | * Definition for singly-linked list. 34 | * struct ListNode { 35 | * int val; 36 | * ListNode *next; 37 | * ListNode(int x) : val(x), next(NULL) {} 38 | * }; 39 | */ 40 | 41 | bool Solution234::isPalindrome(ListNode* head) 42 | { 43 | ListNode *tortoise = head; 44 | ListNode *hare = head; 45 | 46 | //Find start of second half, without including middle node for an odd length LL 47 | while (hare != nullptr) 48 | { 49 | tortoise = tortoise->next; 50 | hare = hare->next; 51 | if (hare != nullptr) hare = hare->next; 52 | } 53 | 54 | //Reverse second half 55 | ListNode *secondHalf = tortoise; 56 | tortoise = reverseList(tortoise); 57 | 58 | //Check second half 59 | ListNode *temp = head; 60 | while (tortoise != nullptr) 61 | { 62 | if (temp->val != tortoise->val) 63 | { 64 | reverseList(secondHalf); 65 | return false; 66 | } 67 | temp = temp->next; 68 | tortoise = tortoise->next; 69 | } 70 | 71 | reverseList(secondHalf); 72 | return true; 73 | 74 | 75 | } 76 | 77 | ListNode* Solution234::reverseList(ListNode* head) 78 | { 79 | ListNode *prev = nullptr; 80 | ListNode *cur = head; 81 | ListNode *next; 82 | 83 | while (cur != nullptr) 84 | { 85 | next = cur->next; 86 | cur->next = prev; 87 | prev = cur; 88 | cur = next; 89 | } 90 | 91 | return prev; 92 | } 93 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/235 - lowestCommonAncestorOfABinarySearchTree.cpp: -------------------------------------------------------------------------------- 1 | #include "235 - lowestCommonAncestorOfABinarySearchTree.h" 2 | 3 | /* 4 | Difficulty: Easy 5 | Please refer to "235. Lowest Common Ancestor of a Binary Search Tree" for the problem statement. 6 | https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/description/ 7 | 8 | Solution: 9 | In a binary search tree, for every node, we know that the value it stores is larger than the values stored in the left subtree, and smaller than the values of the right subtree (generally for equal values they are to the right, or simply not allowed). 10 | In order for a node to be the lowest common ancestor of two other nodes, the two nodes must be on opposite ends of the tree. 11 | Otherwise, we can continue down in the direction that they are both in to get a lower common ancestor! 12 | 13 | Let N be the number of nodes in the tree 14 | Time Complexity: O(N), consider a long tree with 1 leaf and every parent only having a right node. q is the leaf, p is the parent. 15 | Space Complexity: O(1), this is tail recursive! For any given path, we are only moving the node we are considering without needing to wait for additional calculations! 16 | 17 | Tests: 18 | TODO 19 | */ 20 | 21 | /** 22 | * Definition for a binary tree node. 23 | * struct TreeNode { 24 | * int val; 25 | * TreeNode *left; 26 | * TreeNode *right; 27 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 28 | * }; 29 | */ 30 | 31 | TreeNode* Solution235::lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 32 | { 33 | if (root == nullptr) return nullptr; 34 | if (root->val > p->val && root->val > q->val) return lowestCommonAncestor(root->left, p, q); 35 | if (root->val < p->val && root->val < q->val) return lowestCommonAncestor(root->right, p, q); 36 | return root; 37 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/236 - lowestCommonAncestorOfABinaryTree.cpp: -------------------------------------------------------------------------------- 1 | #include "236 - lowestCommonAncestorOfABinaryTree.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Medium 6 | Please refer to "236. Lowest Common Ancestor of a Binary Tree" for the problem statement. 7 | https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/ 8 | 9 | Solution: 10 | We can glean no information from the values in the tree because it isn't a binary search tree or otherwise constrained. 11 | Instead, we use the pointers themselves. We return the root if it's nullpointer or either p or q. 12 | This means that if we perform a recursive call and the result is not nullptr, the subtree we called on contains either p or q, or both. 13 | 14 | With this implemented, the logic then looks like this: 15 | -If the root is nullptr, p, or q, return it 16 | -Set a pointer to the result of calling on the left subtree 17 | -Set a pointer to the result of calling on the right subtree 18 | -If left is nullptr, then it has neither p or q and we can go lower in ancestry by moving right (only considering the result of the right subtree's recursive call) 19 | -If right is nullptr, then the same logic applies and we can go lower in ancestry by moving left 20 | -If neither is nullptr, then the lowest ancestor has to be the root; going either way will lose either p or q 21 | -Note that there is no situation where both the result of the left and right calls are nullptr 22 | 23 | Let N be the number of nodes in the tree 24 | Time Complexity: O(N) 25 | Space Complexity: O(N), consider a tree with 1 leaf, q pointing to that leaf, and p as the parent. Each parent's child is the left pointer. The function will have N - 2 recursive calls on the stack. 26 | */ 27 | 28 | TreeNode* Solution236::lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 29 | { 30 | if (root == nullptr || root == p || root == q) return root; 31 | TreeNode* left = lowestCommonAncestor(root->left, p, q); 32 | TreeNode* right = lowestCommonAncestor(root->right, p, q); 33 | 34 | return (left == nullptr) ? right : (right == nullptr) ? left : root; 35 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/237 - deleteNodeInALinkedList.cpp: -------------------------------------------------------------------------------- 1 | #include "237 - deleteNodeInALinkedList.h" 2 | 3 | /* 4 | Difficulty: Easy 5 | Please refer to "237. Delete Node in a Linked List" for the problem statement. 6 | https://leetcode.com/problems/delete-node-in-a-linked-list/description/ 7 | 8 | Solution: 9 | This is slightly less traditional in that normally you are given a predecessor to the node to be deleted. 10 | However, given the scenarios we will be using this function in, we can safely take the next node's value and place it in our current one, then delete the next node like normal. 11 | 12 | Time Complexity: O(1) 13 | Space Complexity: O(1) 14 | 15 | Be Aware: 16 | -You can actually submit an answer that doesn't actually do any deletion and it will be accepted by LeetCode. 17 | -Make sure that in practice you call delete; otherwise that memory isn't really being freed for further usage. 18 | */ 19 | 20 | /** 21 | * Definition for singly-linked list. 22 | * struct ListNode { 23 | * int val; 24 | * ListNode *next; 25 | * ListNode(int x) : val(x), next(NULL) {} 26 | * }; 27 | */ 28 | 29 | void Solution237::deleteNode(ListNode* node) 30 | { 31 | node->val = node->next->val; 32 | ListNode *temp = node->next; 33 | node->next = node->next->next; 34 | delete temp; 35 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/238 - productOfArrayExceptSelf.cpp: -------------------------------------------------------------------------------- 1 | #include "238 - productOfArrayExceptSelf.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "238. Product of Array Except Self" for the problem statement. 9 | https://leetcode.com/problems/product-of-array-except-self/description/ 10 | 11 | Solution: 12 | Keep an aggregate product going forwards, and an aggregate product going backwards, and update each array spot by multiplying by this aggregate product. 13 | In order to avoid having the ith location include its element in the product, we only update the aggregates AFTER multiplying them in. 14 | That way, for the ith item in an array of size n... 15 | -The forwards aggregate is nums[0]...nums[i - 1] 16 | -The backwards aggregate is nums[i + 1]...nums[n - 1] 17 | -Multiplying these aggregates together provides the desired result at each stage 18 | 19 | Time Complexity: O(N), where N is the size of the input array (two loops through the array) 20 | Space Complexity: O(1) (two integers; NOTE: problem specifies that output array doesn't count as extra space) 21 | 22 | Be Aware: 23 | -This solution, like many solutions, shows that often times an immediately expensive solution (say, O(N) space and O(N) time) can in fact be very similar to the optimal solution. 24 | -This is why it is important to find SOME solution in an interview, because often times with a few hints a better solution will reveal itself. 25 | 26 | Tests: 27 | [1,1] 28 | [2,3] 29 | [1,2,3,4] 30 | [2,4,6,8,10] 31 | [1,10,8,4,7] 32 | */ 33 | 34 | vector Solution238::productExceptSelf(vector& nums) 35 | { 36 | vector output(nums.size(), 1); 37 | int forward = 1; 38 | for (int i = 0; i < output.size(); i++) 39 | { 40 | output[i] *= forward; 41 | forward *= nums[i]; 42 | } 43 | 44 | int backward = 1; 45 | for (int j = output.size() - 1; j >= 0; j--) 46 | { 47 | output[j] *= backward; 48 | backward *= nums[j]; 49 | } 50 | return output; 51 | } 52 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/242 - validAnagram.cpp: -------------------------------------------------------------------------------- 1 | #include "242 - validAnagram.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "242. Valid Anagram" for the problem statement. 9 | https://leetcode.com/problems/valid-anagram/description/ 10 | 11 | Solution: 12 | First check that the strings are the same length; they can't be anagrams of each other if not. 13 | Keep a hash table that maps characters to the number of appearances of that character, and track it for one of the strings. 14 | Then, for the second string, decrement the counter for each character, returning false if the entry is 0 (we are trying to use a letter that we don't have any left of in the first strring!). 15 | If we complete this loop, then we know that they are anagrams, because: 16 | Since they are the same string, if they are not anagrams there must exist a character in t that appears more often than in s. 17 | The conditional in the loop explicitly checks for this. 18 | 19 | Let N be the size of string S in characters. 20 | Time Complexity: O(N) 21 | Space Complexity: O(N) 22 | 23 | Be Aware: 24 | -An alternate approach is to sort both strings and check for equality. 25 | 26 | Time Complexity: O(NlogN) 27 | Space Complexity: O(1) 28 | 29 | -The solution here only beats 6.24% of submissions as of its last submission. Why might this be? 30 | 31 | Tests: 32 | Two empty strings 33 | Two strings, different lengths 34 | "Leet, "code" 35 | "tommarvoloriddle", "iamlordvoldemort" 36 | "deltora", "toradel" 37 | "watchover", "overwatch" 38 | "abcd", "abec" 39 | "abcd", "abdd" 40 | */ 41 | 42 | bool Solution242::isAnagram(string s, string t) 43 | { 44 | if (s.size() != t.size()) return false; 45 | 46 | unordered_map occurrences; 47 | for (int i = 0; i < s.size(); i++) 48 | { 49 | occurrences[s[i]]++; 50 | } 51 | 52 | for (int j = 0; j < t.size(); j++) 53 | { 54 | if (occurrences[t[j]] == 0) return false; 55 | occurrences[t[j]]--; 56 | } 57 | 58 | return true; 59 | } 60 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/257 - binaryTreePaths.cpp: -------------------------------------------------------------------------------- 1 | #include "257 - binaryTreePaths.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "257. Binary Tree Paths" for the problem statement. 9 | https://leetcode.com/problems/binary-tree-paths/description/ 10 | 11 | Solution: 12 | Use a helper recursive function that tracks the string representing the current path and adds to that as it goes down. 13 | The helper should also keep a reference to the vector of strings that will be our result. 14 | 15 | Whenever we encounter a node that has no children, it is a leaf so we append its value to the path and append that path to the result! 16 | 17 | Let N represent the number of nodes in the tree 18 | Time Complexity: O(N), each node visited once and some constant operations are applied 19 | Space Complexity: O(N), every node will be a part of one of the paths in the result. Also, consider the call stack for recursive calls. 20 | 21 | Be Aware: 22 | -We pass in a reference to the result data structure so that each call is considering the same one. This also saves a lot of space on the call stack (we'd otherwise have lots of duplicates during runtime!) 23 | 24 | Tests: 25 | Empty tree 26 | Tree with one node 27 | Full, complete tree with depth 3 28 | Tree with branches ending at various depths up to depth 5 29 | */ 30 | 31 | /** 32 | * Definition for a binary tree node. 33 | * struct TreeNode { 34 | * int val; 35 | * TreeNode *left; 36 | * TreeNode *right; 37 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 38 | * }; 39 | */ 40 | 41 | vector Solution257::binaryTreePaths(TreeNode* root) 42 | { 43 | vector result; 44 | if (root == nullptr) return vector(); 45 | binaryTreePathsHelper(root, "", result); 46 | return result; 47 | } 48 | 49 | void Solution257::binaryTreePathsHelper(TreeNode* root, string curPath, vector& result) 50 | { 51 | if (root == nullptr) return; 52 | if (root->left == nullptr && root->right == nullptr) 53 | { 54 | if (curPath == "") result.push_back(to_string(root->val)); 55 | else result.push_back(curPath + "->" + to_string(root->val)); 56 | } 57 | 58 | if (curPath != "") curPath += "->"; 59 | binaryTreePathsHelper(root->left, curPath + to_string(root->val), result); 60 | binaryTreePathsHelper(root->right, curPath + to_string(root->val), result); 61 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/258 - addDigits.cpp: -------------------------------------------------------------------------------- 1 | #include "258 - addDigits.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Easy 6 | Please refer to "258. Add Digits" for the problem statement. 7 | https://leetcode.com/problems/add-digits/description/ 8 | Note: This code displayed here utilizes the mathematical concept of a digital root to implement the solution without recursion in O(1) runtime. 9 | In an actual interview, knowing the recursive way is enough. Credit to LeetCode user zhiqing_xiao for noting this approach in the Discussion section for the question! 10 | 11 | Alternate Solution: 12 | A more straightforward solution looks like this: 13 | 14 | int addDigits(int num) 15 | { 16 | if(num < 10) return num; 17 | return addDigits(num % 10 + addDigits(num / 10)); 18 | } 19 | 20 | Here, the base case occurs when our input is a one digit-number. The recursive step reduces the problem by summing the ones place with an operation of itself divided by 10, which eventually becomes a sum of digits. 21 | This sum of digits may turn out to be greater than 10, so we perform a recursive call on this result to ensure that we don't need to continue the process on the result. 22 | This will eventually reduce to the answer. 23 | 24 | Solution: 25 | Check out the digital root congruence formula here: https://en.wikipedia.org/wiki/Digital_root#Congruence_formula 26 | 27 | Here it is, for quick reference (for a number n in base b): 28 | -dr(n) = 0 if n == 0 29 | -dr(n) = (b - 1) if n != 0 and n % (b - 1) == 0 30 | -dr(n) = n % (b - 1) if n != 0 and n % (b - 1) != 0 31 | These three statements can then be reduced to a single statement: 32 | -dr_B(n) = 1 + (n - 1) % 9 33 | Examples: 34 | -Bullet 1 -> dr_B(0) = 1 + (-1) % 9 = 0 35 | -Bullet 2 -> dr_B(9) = 1 + (8) % 9 = 10 - 1 = 9 36 | -Bullet 3 -> dr_B(7) = 1 + (6) % 9 = 7 % 9 = 7 37 | 38 | Time Complexity: O(1) 39 | Space Complexity: O(1) 40 | 41 | Be Aware: 42 | -Recall that decimal is base 10, so we are using 10 for the value of b in the digital root formula 43 | -Try comparing average runtimes for both solutions. Is the difference significant? 44 | -Typically writing the alternate solution here is more than enough. I include this solution as the main one because it's cool. ^_^ 45 | 46 | Tests: 47 | 19 48 | 1 49 | 8 50 | 56934 51 | */ 52 | int Solution258::addDigits(int num) 53 | { 54 | return 1 + (num - 1) % 9; 55 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/278 - firstBadVersion.cpp: -------------------------------------------------------------------------------- 1 | #include "278 - firstBadVersion.h" 2 | 3 | /* 4 | Difficulty: Easy 5 | Please refer to "278. First Bad Version" for the problem statement. 6 | https://leetcode.com/problems/first-bad-version/description/ 7 | 8 | Solution: 9 | Use a binary search to narrow down your search to a single bad version. 10 | Consider the middle item: 11 | If it is a bad version, then we know that the first bad version must be in the left half, including mid 12 | If it is not a bad version, then we know that the first bad version must be in the right half, not including mid 13 | We continue the search, narrowing the search space by half until the lower bound passes by the upper bound and we have arrived at our answer. 14 | 15 | Let N be the integer input 16 | Time Complexity: O(logN), total API calls O(logN) 17 | Space Complexity: O(1) 18 | 19 | Be Aware: 20 | -Another solution, which simply involves beginning at the start and continuing until a bad version is encountered, could potentially perform N API calls. 21 | -Though the API function is not shown to the user in the question officially, I have included a trivial one for the sake of allowing this code to compile. Don't make assumptions about the API implementation! 22 | 23 | Tests: 24 | 1 as first bad version (FBV), 5 versions 25 | 3 as FBV, 5 versions 26 | 4 as FBV, 5 versions 27 | 5 as FBV, 5 versions 28 | 256 as FBV, 513 versions 29 | */ 30 | 31 | 32 | int Solution278::firstBadVersion(int n) 33 | { 34 | int lower = 1, upper = n, mid; 35 | while (lower < upper) 36 | { 37 | mid = lower + (upper - lower) / 2; 38 | if (!isBadVersion(mid)) lower = mid + 1; 39 | else upper = mid; 40 | } 41 | return lower; 42 | } 43 | 44 | 45 | bool Solution278::isBadVersion(int n) 46 | { 47 | return n >= 25; 48 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/292 - nimGame.cpp: -------------------------------------------------------------------------------- 1 | #include "292 - nimGame.h" 2 | #include "config.h" 3 | 4 | /* 5 | Difficulty: Easy 6 | Please refer to "292. Nim Game" for the problem statement. 7 | https://leetcode.com/problems/nim-game/description/ 8 | 9 | Solution: 10 | The key is to leverage the hint that they give you: if you start with a 4, then no matter what you do you will lose since you have to go first. 11 | If you have 5, 6, or 7, you can reverse the situation and hand off the predicament to your friend who goes second, winning you the game. 12 | 8 once again shifts the predicament back over to you, and so on and so forth. 13 | 14 | Thus, all you have to do is check to see if the input is divisible by 4. If it is, then you can't win. Otherwise you're fine! 15 | 16 | Time Complexity: O(1) 17 | Space Complexity: O(1) 18 | */ 19 | 20 | bool Solution292::canWinNim(int n) 21 | { 22 | return !(n % 4 == 0); 23 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/293 - flipGame.cpp: -------------------------------------------------------------------------------- 1 | #include "293 - flipGame.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "293. Flip Game" for the problem statement. Note that this problem is available for premium Leetcode users only. 9 | https://leetcode.com/problems/flip-game/description/ 10 | 11 | Solution: 12 | Simply iterate through the string, and at any point there are consecutive '+' symbols change the pair to '-' and add that representation to the result. 13 | Be aware: 14 | -There are more efficient ways to perform the mechanics of what is happening here. Using library calls is not always efficient. 15 | Tests: 16 | Empty 17 | ++++ 18 | -+-+- 19 | ++--+++ 20 | +-+--++- 21 | - 22 | + 23 | */ 24 | vector Solution293::generatePossibleNextMoves(string s) 25 | { 26 | vector result; 27 | for (int i = 0; i < (int)s.length() - 1; i++) 28 | { 29 | if (s[i] == '+' && s[i + 1] == '+') 30 | { 31 | string temp = s; 32 | temp.replace(i, 2, "--"); 33 | result.push_back(temp); 34 | } 35 | } 36 | 37 | return result; 38 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/300 - longestIncreasingSubsequence.cpp: -------------------------------------------------------------------------------- 1 | #include "300 - longestIncreasingSubsequence.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "300. Longest Increasing Subsequence" for the problem statement. 9 | https://leetcode.com/problems/longest-increasing-subsequence/description/ 10 | 11 | Solution: 12 | Credit to Leetcode user DietPepsi with a similar explanation of this problem. 13 | https://discuss.leetcode.com/topic/28738/java-python-binary-search-o-nlogn-time-with-explanation 14 | 15 | Our tails array stores the smallest tail for all increasing subsequences of length i + 1 in tails[i] 16 | 17 | We see that as we iterate through our numbers, there will be one of two scenarios: 18 | -if x is larger than any of our tails, we can append it to our existing subsequences. This essentially means x will be in tails[i + 1], if our longest increasing sequence has so far been in tails[i] 19 | -if tails[i - 1] < x <= tails[i], update tails[i], update tails[i]. Since we can construct a sequence that's length i + 1 that ends with something greater than x, and the smallest tail right before is less than x, it is safe to replace whatever is in tails[i] with x. 20 | 21 | From this, we can easily see that the answer at the end will be size that tails managed to get to. 22 | 23 | Because the tails array is increasing, we can reason that for each element in nums, we are performing a binary search. 24 | Thus, if N is the size of the nums array, 25 | 26 | Time Complexity: O(NlogN) 27 | Space Complexity: O(N) 28 | 29 | Be Aware: 30 | -The library function lower_bound returns an element pointing to the first element in the range [first, last) which does not compare less than val. It operates in logN time. 31 | -This is a classic dynamic programming problem! 32 | 33 | Tests: 34 | Empty vector 35 | [1] 36 | [1, 2] 37 | [10, 9] 38 | [10, 9, 2, 5, 3, 7, 101, 18] 39 | [1, 2, 3, 4, 5] 40 | [5, 4, 3, 2, 1] 41 | [1, 9, 2, 8 , 3, 7, 4, 6, 5] 42 | */ 43 | 44 | int Solution300::lengthOfLIS(vector& nums) 45 | { 46 | vector tails; 47 | tails.reserve(nums.size()); 48 | 49 | for (int i = 0; i < nums.size(); i++) 50 | { 51 | auto loc = lower_bound(tails.begin(), tails.end(), nums[i]); 52 | if (loc == tails.end()) tails.push_back(nums[i]); 53 | else *loc = nums[i]; 54 | } 55 | 56 | return tails.size(); 57 | } 58 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/328 - oddEvenLinkedList.cpp: -------------------------------------------------------------------------------- 1 | #include "328 - oddEvenLinkedList.h" 2 | 3 | /* 4 | Difficulty: Easy 5 | Please refer to "328. Odd Even Linked List" for the problem statement. 6 | https://leetcode.com/problems/odd-even-linked-list/description/ 7 | 8 | Solution: 9 | Initialize two pointers, one to the head to represent the beginning of the odd list, one to head's next if it exists to represent the beginning of the even list. 10 | Treat the linked list as two separate linked lists woven together, and reassign pointers such that all the evens are in one linked list and the odds in the other. 11 | After that is complete, it's just a matter of pointing the last element in the odd linked list to the head of the even linked list. 12 | 13 | Let N be the number of nodes in the input linked list. 14 | Time Complexity: O(N) 15 | Space Complexity: O(1) 16 | 17 | Be Aware: 18 | -Make sure you keep track of where all of your pointers are. 19 | 20 | Tests: 21 | Empty list 22 | 1 23 | 1->2 24 | 1->2->3 25 | 1->2->3->4 26 | */ 27 | 28 | /** 29 | * Definition for singly-linked list. 30 | * struct ListNode { 31 | * int val; 32 | * ListNode *next; 33 | * ListNode(int x) : val(x), next(NULL) {} 34 | * }; 35 | */ 36 | 37 | ListNode* Solution328::oddEvenList(ListNode* head) 38 | { 39 | if (head == nullptr) return nullptr; 40 | ListNode *odd = head; 41 | ListNode *even = head->next; 42 | ListNode *even_head = even; 43 | 44 | while (even != nullptr && even->next != nullptr) 45 | { 46 | odd->next = even->next; 47 | odd = odd->next; 48 | even->next = odd->next; 49 | even = even->next; 50 | } 51 | 52 | odd->next = even_head; 53 | 54 | return head; 55 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/344 - reverseString.cpp: -------------------------------------------------------------------------------- 1 | #include "344 - reverseString.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "344. Reverse String" for the problem statement. 9 | https://leetcode.com/problems/reverse-string/description/ 10 | 11 | Solution: 12 | The first character will become the last, second the second to last, so on and so forth. 13 | Iterate forwards and backwards and swap appropriately, until the iterators meet halfway. 14 | Time Complexity: O(N) 15 | Space Complexity: O(1) 16 | Be Aware: 17 | -There are many good ways to solve this problem. 18 | -Some companies like to use this question as a worksheet question at career fairs, because there are so many answers and it is relatively quick and easy. 19 | -This is a good warmup if it has been a long time since you have coded in a particular language. 20 | Tests: 21 | "" 22 | "Hello world!" 23 | "A" 24 | "Even" 25 | "Odd" 26 | */ 27 | 28 | string Solution344::reverseString(string s) 29 | { 30 | int i = 0, j = s.length() - 1; 31 | while (i < j) 32 | { 33 | swap(s[i++], s[j--]); 34 | } 35 | 36 | return s; 37 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/412 - fizzBuzz.cpp: -------------------------------------------------------------------------------- 1 | #include "412 - fizzBuzz.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "412. Fizz Buzz" for the problem statement. 9 | https://leetcode.com/problems/fizz-buzz/description/ 10 | 11 | Solution: 12 | This is a very basic algorithm. Just loop through from 1 up until n and examine the number, adding the appropriate string to your result as you go. 13 | 14 | Time Complexity: O(n) 15 | Space Complexity: O(n), just for storing the result 16 | 17 | Be Aware: 18 | -This is a good example of simplicity vs performance. This code is not necessarily the most efficient code in terms of runtime. However, it is very easy to read. 19 | 20 | Tests: 21 | Call with n = 31 to get a good spread of all conditional branches. 22 | 23 | */ 24 | vector Solution412::fizzBuzz(int n) 25 | { 26 | vector result; 27 | 28 | for (int i = 1; i <= n; i++) 29 | { 30 | if (i % 15 == 0) result.push_back("FizzBuzz"); 31 | else if (i % 5 == 0) result.push_back("Buzz"); 32 | else if (i % 3 == 0) result.push_back("Fizz"); 33 | else result.push_back(to_string(i)); 34 | } 35 | 36 | return result; 37 | 38 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/419 - battleshipsInABoard.cpp: -------------------------------------------------------------------------------- 1 | #include "419 - battleshipsInABoard.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "419. Battleships in a Board" for the problem statement. 9 | https://leetcode.com/problems/battleships-in-a-board/description/ 10 | 11 | Solution: 12 | This can be solved by marking battleships using either BFS or DFS; however, we can leverage what we know about their positioning to get a faster solution. 13 | 14 | We know that a ship of length N will occupy either a 1xN row or a Nx1 column. 15 | We also know that ships will not be adjacent to each other; that is, there is either a border or water between all battleships. 16 | 17 | This means that we can iterate through the board and count certain X's because they denote NEW battleships. Other X's that don't fit the criteria are part of battleships that have already been counted. 18 | 19 | If we go top to bottom, left to right, we know that we are part of a new battleship if we encounter an X and neither the slot directly above or to the left of it is an X. 20 | We simply count the number of these X's to get the number of battleships on the board. 21 | 22 | Time Complexity: O(N) 23 | Space Complexity: O(1) 24 | Advantages: 1 pass, no board modification 25 | 26 | Be Aware: 27 | -Why can't we use this trick in other BFS/DFS board problems? 28 | -If we were to iterate bottom to top, right to left, what would need to change about the X's that we are counting? 29 | 30 | Tests: 31 | X..X 32 | ...X 33 | XX.. 34 | 35 | X 36 | 37 | .. 38 | .. 39 | 40 | ..... 41 | .XX.X 42 | ....X 43 | ..X.. 44 | ....X 45 | */ 46 | 47 | int Solution419::countBattleships(vector>& board) 48 | { 49 | int count = 0; 50 | if (board.size() == 0) return 0; 51 | if (board[0].size() == 0) return 0; 52 | 53 | for (int i = 0; i < board.size(); i++) 54 | { 55 | for (int j = 0; j < board[0].size(); j++) 56 | { 57 | if (board[i][j] == 'X') 58 | { 59 | if ((i == 0 || board[i - 1][j] != 'X') && (j == 0 || board[i][j - 1] != 'X')) count++; 60 | } 61 | } 62 | } 63 | 64 | return count; 65 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/461 - hammingDistancecpp.cpp: -------------------------------------------------------------------------------- 1 | #include "461 - hammingDistance.h" 2 | 3 | /* 4 | Difficulty: Easy 5 | Please refer to "461. Hamming Distance" for the problem statement. 6 | https://leetcode.com/problems/hamming-distance/description/ 7 | 8 | Solution: 9 | In this situation, since we know the data type and the range of values, we can figure out the number of bits we have to examine for any representation of input. 10 | Also, we can utilize the fact that if two bits are different, XOR'ing them together will produce 1. 11 | 12 | As such, we simply loop through each bit, examining one bit from each input, and adding the result of their XOR to a running tally. 13 | 14 | Time Complexity: O(1), loop will iterate 31 times 15 | Space Complexity: O(1) 16 | 17 | Be Aware: 18 | -Are there faster or alternative ways to do this? 19 | -What if we didn't know the size in bits of the input? 20 | 21 | Tests: 22 | 1001 23 | 1000 24 | 25 | 1111 26 | 0000 27 | 28 | 1011 29 | 0110 30 | */ 31 | 32 | int Solution461::hammingDistance(int x, int y) 33 | { 34 | int result = 0; 35 | for (int i = 0; i < 31; i++) 36 | { 37 | int x_bit = x & 1; 38 | int y_bit = y & 1; 39 | result += x_bit ^ y_bit; 40 | x >>= 1; 41 | y >>= 1; 42 | } 43 | return result; 44 | } 45 | -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/540 - singleElementInASortedArray.cpp: -------------------------------------------------------------------------------- 1 | #include "540 - singleElementInASortedArray.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Medium 8 | Please refer to "540. Single Element in a Sorted Array" for the problem statement. 9 | https://leetcode.com/problems/single-element-in-a-sorted-array/description/ 10 | 11 | Solution: 12 | The trivial answer would simply be to iterate through the array and find the first number that doesn't have its twin next to it. 13 | 14 | However, it can be done faster, via binary search, leveraging the fact that there are no duplicate pairs (e.g. [4,4,4,4,5] will never appear). 15 | Whenever we consider a element at a midpoint in our binary search, we first check to see if is the single element by looking at the elements on either end. 16 | If it isn't it, then we determine which half to go to by figuring out if we have passed the single element or not. 17 | 18 | Data: [1,1,2,2,3,4,4,5,5] 19 | Index:[0,1,2,3,4,5,6,7,8] 20 | 21 | Notice that if we haven't passed the singleton, the first twin falls on an even index and the second falls on an odd index. 22 | However, if we have passed the singleton then the first twin falls on an odd index and the second falls on an even index. 23 | Using this, and the parity of the midpoint we are considering, we can check if we have passed the singleton or not, effectively determining which half we should consider. 24 | 25 | Time Complexity: O(logN) 26 | Space Complexity: O(1) 27 | 28 | Be Aware: 29 | -What if we were allowed to have duplicate pairings? Would this algorithm still work? Why or why not? 30 | 31 | Tests: 32 | [1,2,2,3,3] 33 | [1,1,2,2,3] 34 | [1,1,2,3,3] 35 | [1] 36 | [1,1,2] 37 | [1,1,2,2,3,3,5,5,9] 38 | */ 39 | 40 | int Solution540::singleNonDuplicate(vector& nums) 41 | { 42 | int low = 0; 43 | int high = nums.size() - 1; 44 | if (nums.size() == 1) return nums[0]; 45 | 46 | int mid; 47 | while (low <= high) 48 | { 49 | mid = low + (high - low) / 2; 50 | if (mid == 0 && nums[mid + 1] != mid) return nums[mid]; 51 | if (mid == nums.size() - 1 && nums[mid - 1] != nums[mid]) return nums[mid]; 52 | if (nums[mid - 1] != nums[mid] && nums[mid + 1] != nums[mid]) return nums[mid]; 53 | 54 | if (mid % 2 == 0) 55 | { 56 | if (nums[mid + 1] != nums[mid]) high = mid - 1; 57 | else low = mid + 1; 58 | } 59 | else 60 | { 61 | if (nums[mid - 1] != nums[mid]) high = mid - 1; 62 | else low = mid + 1; 63 | } 64 | } 65 | 66 | return nums[low]; 67 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/617 - mergeTwoBinaryTrees.cpp: -------------------------------------------------------------------------------- 1 | #include "617 - mergeTwoBinaryTrees.h" 2 | 3 | /* 4 | Difficulty: Easy 5 | Please refer to "617. Merge Two Binary Trees" for the problem statement. 6 | https://leetcode.com/problems/merge-two-binary-trees/description/ 7 | 8 | Solution: 9 | We perform a traversal through both trees. If both exist then we just merge them as specified. 10 | Otherwise, if only one exists then we just add that one node in the right spot and continue onwards left and right. 11 | The key is to realize that since each call is returning the new node, we have the call also set its left and rights to the return value of the call to the left and right subtree. 12 | By doing so, we can construct the tree recursively. 13 | 14 | Let M be the number of nodes in t1, and N be the number of nodes in t2 15 | Time Complexity: O(M + N). Only root overlaps. 16 | Space Complexity: TODO 17 | 18 | Be Aware: 19 | -Is there a way to do this iteratively? 20 | 21 | Tests: 22 | Trees with total overlap 23 | Trees with minimal overlap 24 | Trees where one is a subtree of the other 25 | */ 26 | 27 | /** 28 | * Definition for a binary tree node. 29 | * struct TreeNode { 30 | * int val; 31 | * TreeNode *left; 32 | * TreeNode *right; 33 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 34 | * }; 35 | */ 36 | 37 | TreeNode* Solution617::mergeTrees(TreeNode* t1, TreeNode* t2) 38 | { 39 | if (t1 == nullptr && t2 == nullptr) return nullptr; 40 | if (t1 != nullptr && t2 != nullptr) 41 | { 42 | TreeNode* toAdd = new TreeNode(t1->val + t2->val); 43 | toAdd->left = mergeTrees(t1->left, t2->left); 44 | toAdd->right = mergeTrees(t1->right, t2->right); 45 | return toAdd; 46 | } 47 | else if (t1 != nullptr) 48 | { 49 | TreeNode* toAdd = new TreeNode(t1->val); 50 | toAdd->left = mergeTrees(t1->left, nullptr); 51 | toAdd->right = mergeTrees(t1->right, nullptr); 52 | return toAdd; 53 | } 54 | else 55 | { 56 | TreeNode* toAdd = new TreeNode(t2->val); 57 | toAdd->left = mergeTrees(nullptr, t2->left); 58 | toAdd->right = mergeTrees(nullptr, t2->right); 59 | return toAdd; 60 | } 61 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/Leetcode Source Files/657 - judgeRouteCircle.cpp: -------------------------------------------------------------------------------- 1 | #include "657 - judgeRouteCircle.h" 2 | #include "config.h" 3 | 4 | using namespace std; 5 | 6 | /* 7 | Difficulty: Easy 8 | Please refer to "657. Judge Route Circle" for the problem statement. 9 | https://leetcode.com/problems/judge-route-circle/description/ 10 | 11 | Solution: 12 | Keep two counters, one for the amount moved up/down and the other for the amount moved left/right. 13 | Iterate through the string, making the appropriate addition/subtraction to the appropriate counter. 14 | Afterwards, both counters should be 0. Otherwise our robot has moved to a different location! 15 | 16 | Let N be the length of the input string 17 | Time Complexity: O(N) 18 | Space Complexity: O(1) 19 | 20 | Be Aware: 21 | -This is a very simple problem that should take < 5 minutes in an interview. 22 | -It doesn't matter what you add or subtract, so long as left is opposite of right with equal weight and up is opposite of down with equal weight. 23 | 24 | Tests: 25 | UD 26 | DU 27 | LR 28 | RL 29 | U 30 | L 31 | RRLLUDUDLRLRRLLR 32 | UURRDLLRLDR 33 | Empty string 34 | */ 35 | 36 | bool Solution657::judgeCircle(string moves) 37 | { 38 | int up = 0; 39 | int right = 0; 40 | for (int i = 0; i < moves.size(); i++) 41 | { 42 | switch (moves[i]) 43 | { 44 | case 'U': 45 | up++; 46 | break; 47 | case 'D': 48 | up--; 49 | break; 50 | case 'L': 51 | right--; 52 | break; 53 | case 'R': 54 | right++; 55 | } 56 | } 57 | 58 | return up == 0 && right == 0; 59 | } -------------------------------------------------------------------------------- /LeetcodeQuestions/SolutionNavigator/SolutionNavigator.cpp: -------------------------------------------------------------------------------- 1 | // SolutionNavigator.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | 6 | int main() 7 | { 8 | std::cout << "Hello World!\n"; 9 | } 10 | 11 | // Run program: Ctrl + F5 or Debug > Start Without Debugging menu 12 | // Debug program: F5 or Debug > Start Debugging menu 13 | 14 | // Tips for Getting Started: 15 | // 1. Use the Solution Explorer window to add/manage files 16 | // 2. Use the Team Explorer window to connect to source control 17 | // 3. Use the Output window to see build output and other messages 18 | // 4. Use the Error List window to view errors 19 | // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project 20 | // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file 21 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## Motivation 2 | 3 | As a CS student at UCLA, securing a internship as soon as possible was something that I felt that I had struggled a lot with during undergrad. There was so much out there that it seemed overwhelming to even begin, and famous books like "Cracking the Coding Interview" had all of their interview problems posted in Java, not C++. 4 | Of course, there's no denying that the easiest way to improve at something is to practice it a lot. My hope is that the information provided here makes it easier for aspiring CS students to practice, secure awesome internships and jobs for themselves. 5 | The repository is meant to serve as quick reference for people to find explanations for coding problems they encounter, or quickly review questions that they have solved long ago. 6 | 7 | It stores solutions to problems posted on Leetcode.com, with explanations, some tests to consider, and small gotchas to be aware of. 8 | All of these questions have been done in C++ where possible, to provide a foundation for newer UCLA students that are still taking CS 31, CS 32, and CS 33. 9 | Of course, even if you are more experienced, from another school, or out of school entirely you are welcome to check out these C++ solutions! 10 | 11 | 12 | As of the creation of this document there are 39 Easy, 30 Medium, and 6 Hards for a total of 75 questions to practice, hopefully catering to students of all experience levels. 13 | 14 | 15 | ## Navigation 16 | All solution files can be found in the Questions/Question subfolder. 17 | 18 | Navigation is intended to be as straightforward as possible, both to make things easy to find and make it easier for me to add new solutions. 19 | Every question is marked by the number assigned to it on leetcode.com, with most relevant information contained inside the .cpp files. 20 | 21 | Example: 202 - happyNumber.cpp corresponds to Problem 202. on Leetcode, of the same name. 22 | 23 | Each .cpp file, in addition to the solution to the problem, contains a comment header with: 24 | 25 | * Difficulty of the problem 26 | * Link to the problem on leetcode.com 27 | * Solution in words, with the intuition and explanation 28 | * Most will also consider time and space complexity 29 | * Comments of structures provided for the problem, implemented in the .h files and provided by default by Leetcode when completing the problem 30 | 31 | Good luck getting those job offers!! :) 32 | 33 | ## Contact 34 | 35 | James Wang - You can contact me at jameswang97 at ucla.edu (formatted to prevent spambots). 36 | --------------------------------------------------------------------------------