diff --git a/src/problems/1023.camelcase-matching.jl b/src/problems/1023.camelcase-matching.jl index 7a428f7e0..9f6721d8a 100644 --- a/src/problems/1023.camelcase-matching.jl +++ b/src/problems/1023.camelcase-matching.jl @@ -74,11 +74,9 @@ function matches(query, pattern) end i += 1 end - return j > length(pattern) && all(!isuppercase, query[i:end]) + return j > length(pattern) && all(islowercase, @view(query[i:end])) end -function camelMatch(queries, pattern) - return [matches(query, pattern) for query in queries] -end +camelMatch(queries, pattern) = matches.(queries, Ref(pattern)) ## @lc code=end diff --git a/src/unresolved/28.implement-strstr.jl b/src/problems/28.implement-strstr.jl similarity index 65% rename from src/unresolved/28.implement-strstr.jl rename to src/problems/28.implement-strstr.jl index c86c7c83f..5d30b1c39 100644 --- a/src/unresolved/28.implement-strstr.jl +++ b/src/problems/28.implement-strstr.jl @@ -1,8 +1,8 @@ # --- # title: 28. Implement strStr() # id: problem28 -# author: Tian Jun -# date: 2020-10-31 +# author: Pixia1234 +# date: 2024-07-13 # difficulty: Easy # categories: Two Pointers, String # link: @@ -61,5 +61,24 @@ ## @lc code=start using LeetCode -## add your code here: +function strStr(haystack::String, needle::String) + needle == "" && return 0 + for i in 1:(length(haystack) - length(needle) + 1) + if @view(haystack[i:(i + length(needle) - 1)]) == needle + return i - 1 # Notice that Julia is 1-indexed, and here we need 0-indexed so minus 1 + end + end + return -1 +end + +function strStr2(haystack::AbstractString, needle::AbstractString) + # border case + isempty(needle) && return 0 + length(needle) > length(haystack) && return -1 + # match needle + needle == @view(haystack[1:length(needle)]) && return 0 + # recursive search + ind = @views strStr2(haystack[2:end], needle) + return ind == -1 ? -1 : ind + 1 +end ## @lc code=end diff --git a/src/unresolved/29.divide-two-integers.jl b/src/problems/29.divide-two-integers.jl similarity index 76% rename from src/unresolved/29.divide-two-integers.jl rename to src/problems/29.divide-two-integers.jl index 7bdd22816..e64f3f42f 100644 --- a/src/unresolved/29.divide-two-integers.jl +++ b/src/problems/29.divide-two-integers.jl @@ -1,8 +1,8 @@ # --- # title: 29. Divide Two Integers # id: problem29 -# author: Tian Jun -# date: 2020-10-31 +# author: Pixia1234 +# date: 2024-07-17 # difficulty: Medium # categories: Math, Binary Search # link: @@ -69,5 +69,18 @@ ## @lc code=start using LeetCode -## add your code here: +function divide(dividend::Int, divisor::Int)::Int + sign = (dividend < 0) ⊻ (divisor < 0) + dividend, divisor = abs(dividend), abs(divisor) + result = 0 + while dividend >= divisor + shift = 0 + while dividend >= (divisor << shift) + shift += 1 + end + dividend -= divisor << (shift - 1) + result += 1 << (shift - 1) + end + return sign ? -result : result +end ## @lc code=end diff --git a/src/unresolved/38.count-and-say.jl b/src/problems/38.count-and-say.jl similarity index 71% rename from src/unresolved/38.count-and-say.jl rename to src/problems/38.count-and-say.jl index ad4aa4b73..504634a2c 100644 --- a/src/unresolved/38.count-and-say.jl +++ b/src/problems/38.count-and-say.jl @@ -1,8 +1,8 @@ # --- # title: 38. Count and Say # id: problem38 -# author: Tian Jun -# date: 2020-10-31 +# author: Pixia1234 +# date: 2024-07-17 # difficulty: Easy # categories: String # link: @@ -62,5 +62,26 @@ ## @lc code=start using LeetCode -## add your code here: +function countandsay(n::Int) + # Base case + n == 1 && return "1" + # Get the previous term + previous_term = countandsay(n - 1) + # Generate the current term by "saying" the previous term + current_term = "" + count = 0 + current_char = previous_term[1] + + for char in previous_term + if char == current_char + count += 1 + else + current_term *= string(count) * current_char + current_char = char + count = 1 + end + end + # Append the last group + current_term * string(count) * current_char +end ## @lc code=end diff --git a/src/unresolved/40.combination-sum-ii.jl b/src/problems/40.combination-sum-ii.jl similarity index 53% rename from src/unresolved/40.combination-sum-ii.jl rename to src/problems/40.combination-sum-ii.jl index 6051eb3d7..563a24267 100644 --- a/src/unresolved/40.combination-sum-ii.jl +++ b/src/problems/40.combination-sum-ii.jl @@ -1,8 +1,8 @@ # --- # title: 40. Combination Sum II # id: problem40 -# author: Tian Jun -# date: 2020-10-31 +# author: Pixia1234 +# date: 2024-07-18 # difficulty: Medium # categories: Array, Backtracking # link: @@ -57,5 +57,29 @@ ## @lc code=start using LeetCode -## add your code here: +function combinationSum(candidates::AbstractVector{Int}, target::Int) + res = Vector{Vector{Int}}() + return combinationSum!(sort(candidates), target, Int[], res) +end + +function combinationSum!( + candidates::AbstractVector{Int}, + target::Int, + path::AbstractVector{Int}, + res::Vector{Vector{Int}}, +) + # if the target is 0, we find a solution + target == 0 && return push!(res, copy(path)) + length(candidates) == 0 || target < first(candidates) && return res + + # use @view to avoid copying the array + for (i, candidate) in enumerate(candidates) + i > 1 && candidate == candidates[i - 1] && continue + candidate > target && break + subcandidates = @view(candidates[1:length(candidate) .!= i]) # skip the current candidate + combinationSum!(subcandidates, target - candidate, push!(path, candidate), res) + end + return res +end + ## @lc code=end diff --git a/src/unresolved/46.permutations.jl b/src/problems/46.permutations.jl similarity index 53% rename from src/unresolved/46.permutations.jl rename to src/problems/46.permutations.jl index 9c8989eab..ce01193cc 100644 --- a/src/unresolved/46.permutations.jl +++ b/src/problems/46.permutations.jl @@ -1,8 +1,8 @@ # --- # title: 46. Permutations # id: problem46 -# author: Tian Jun -# date: 2020-10-31 +# author: Pixia1234 +# date: 2024-07-19 # difficulty: Medium # categories: Backtracking # link: @@ -50,5 +50,26 @@ ## @lc code=start using LeetCode -## add your code here: +permutation(nums::Vector{Int}) = permutation!(copy(nums)) +function permutation!(nums::Vector{Int}) + sort!(nums) + res = Vector{Vector{Int}}() + n = length(nums) + sizehint!(res, factorial(n)) + function dfs(nums::Vector{Int}, path::Vector{Int}, used::Vector{Bool}, len::Int) + if len == n # alternatively, len = sum(used) + push!(res, copy(path)) + return nothing + end + for i in 1:n + used[i] && continue + used[i] = true + path[len + 1] = nums[i] + dfs(nums, path, used, len + 1) + used[i] = false + end + end + dfs(nums, Vector{Int}(undef, n), fill(false, n), 0) + return res +end ## @lc code=end diff --git a/src/unresolved/47.permutations-ii.jl b/src/problems/47.permutations-ii.jl similarity index 53% rename from src/unresolved/47.permutations-ii.jl rename to src/problems/47.permutations-ii.jl index 5a7df9f5e..c7aa5bbc2 100644 --- a/src/unresolved/47.permutations-ii.jl +++ b/src/problems/47.permutations-ii.jl @@ -44,5 +44,27 @@ ## @lc code=start using LeetCode -## add your code here: +function permutationII(nums::Vector{Int})::Vector{Vector{Int}} + res = Vector{Vector{Int}}() + n = length(nums) + function dfs(nums::Vector{Int}, path::Vector{Int}, used::Vector{Bool}) + if length(path) == n + push!(res, copy(path)) + return nothing + end + @inbounds for i in 1:n + if used[i] || (i > 1 && nums[i] == nums[i - 1] && !used[i - 1]) + continue + end + push!(path, nums[i]) + used[i] = true + dfs(nums, path, used) + pop!(path) + used[i] = false + end + end + sort!(nums) + dfs(nums, Vector{Int}(), fill(false, n)) + return res +end ## @lc code=end diff --git a/test/problems/1023.camelcase-matching.jl b/test/problems/1023.camelcase-matching.jl index 2a5fe37b5..04c59f063 100644 --- a/test/problems/1023.camelcase-matching.jl +++ b/test/problems/1023.camelcase-matching.jl @@ -1,5 +1,5 @@ @testset "1023.camelcase-matching.jl" begin - @test camelMatch(("FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"),"FB") == ("1,0,1,1,0") - @test camelMatch(("FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"),"FoBa") == ("1,0,1,0,0") - @test camelMatch(("FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"),"FoBaT") == ("0,1,0,0,0") + @test camelMatch(["FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"],"FB") == [true,false,true,true,false] + @test camelMatch(["FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"],"FoBa") == [true,false,true,false,false] + @test camelMatch(["FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"],"FoBaT") == [false,true,false,false,false] end diff --git a/test/problems/28.implement-strstr.jl b/test/problems/28.implement-strstr.jl new file mode 100644 index 000000000..407b0df69 --- /dev/null +++ b/test/problems/28.implement-strstr.jl @@ -0,0 +1,10 @@ +@testset "28.implement-strstr.jl" begin + @test strStr("hello", "ll") == 2 + @test strStr("aaaaa", "bba") == -1 + @test strStr("sadbutsad", "sad") == 0 + @test strStr("leetcode", "leeto") == -1 + @test strStr2("hello", "ll") == 2 + @test strStr2("aaaaa", "bba") == -1 + @test strStr2("sadbutsad", "sad") == 0 + @test strStr2("leetcode", "leeto") == -1 +end diff --git a/test/problems/29.divide-two-integers.jl b/test/problems/29.divide-two-integers.jl new file mode 100644 index 000000000..77c434765 --- /dev/null +++ b/test/problems/29.divide-two-integers.jl @@ -0,0 +1,6 @@ +@testset "29.divide-two-integers.jl" begin + @test divide(10, 3) == 3 + @test divide(7, -3) == -2 + @test divide(0, 1) == 0 + @test divide(1, 1) == 1 +end diff --git a/test/problems/38.count-and-say.jl b/test/problems/38.count-and-say.jl new file mode 100644 index 000000000..78b7de06e --- /dev/null +++ b/test/problems/38.count-and-say.jl @@ -0,0 +1,6 @@ +@testset "38.count-and-say.jl" begin + @test countandsay(1) == "1" + @test countandsay(4) == "1211" + @test countandsay(5) == "111221" + @test countandsay(6) == "312211" +end diff --git a/test/problems/40.combination-sum-ii.jl b/test/problems/40.combination-sum-ii.jl new file mode 100644 index 000000000..dfc5f928e --- /dev/null +++ b/test/problems/40.combination-sum-ii.jl @@ -0,0 +1,5 @@ +@testset "40.combination-sum-ii.jl" begin + @test combinationSum([10, 1, 2, 7, 6, 1, 5], 8) == + [[1, 1, 6], [1, 2, 5], [1, 7], [2, 6]] + @test combinationSum([2, 5, 2, 1, 2], 5) == [[1, 2, 2], [5]] +end diff --git a/test/problems/46.permutations.jl b/test/problems/46.permutations.jl new file mode 100644 index 000000000..f9ce03c17 --- /dev/null +++ b/test/problems/46.permutations.jl @@ -0,0 +1,6 @@ +@testset "46.permutations.jl" begin + @test sort!(permutation([1, 3, 2])) == + [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] + @test permutation([0, 1]) == [[0, 1], [1, 0]] + @test permutation([1]) == [[1]] +end diff --git a/test/problems/47.permutations-ii.jl b/test/problems/47.permutations-ii.jl new file mode 100644 index 000000000..a1541455e --- /dev/null +++ b/test/problems/47.permutations-ii.jl @@ -0,0 +1,5 @@ +@testset "47.permutations-ii.jl" begin + @test permutationII([1, 1, 2]) == [[1, 1, 2], [1, 2, 1], [2, 1, 1]] + @test permutationII([1, 2, 3]) == + [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] +end