Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ pub fn build(b: *std.Build) void {
.name = "knapsack.zig",
.category = "dynamicProgramming"
});
if (std.mem.eql(u8, op, "dp/longestIncreasingSubsequence"))
build_algorithm(b, .{
.optimize = optimize,
.target = target,
.name = "longestIncreasingSubsequence.zig",
.category = "dynamicProgramming"
});

// Math algorithms
if (std.mem.eql(u8, op, "math/ceil"))
Expand Down
68 changes: 68 additions & 0 deletions dynamicProgramming/longestIncreasingSubsequence.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const std = @import("std");
const print = std.debug.print;
const testing = std.testing;
const ArrayList = std.ArrayList;

// Function that returns the lower bound in O(logn)
pub fn lower_bound(arr: []const i32, key: i32) usize {
var lo: usize = 0;
var hi: usize = arr.len;

while (lo < hi) {
const mid: usize = lo + (hi - lo) / 2;
if (key <= arr[mid]) {
hi = mid;
} else {
lo = mid + 1;
}
}

if (lo < arr.len and arr[lo] < key) {
lo += 1;
}

return lo;
}

// Function that returns the length of the longest increasing subsequence of an array
// Runs in O(nlogn) using the lower bound function
// Arguments:
// arr: the passed array
// allocator: Any std.heap type allocator
pub fn lis(arr: []const i32, allocator: anytype) usize {
var v = ArrayList(i32).init(allocator);
defer v.deinit();

const n = arr.len;

for (0..n) |i| {
const it = lower_bound(v.items, arr[i]);
if (it == v.items.len) {
_ = v.append(arr[i]) catch return 0;
} else {
v.items[it] = arr[i];
}
}

return v.items.len;
}

test "testing longest increasing subsequence function" {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();

const v = [4]i32{ 1, 5, 6, 7 };
try testing.expect(lis(&v, gpa.allocator()) == 4);

const v2 = [5]i32{ 1, -1, 5, 6, 7 };
try testing.expect(lis(&v2, gpa.allocator()) == 4);

const v3 = [5]i32{ 1, 2, -1, 0, 1 };
try testing.expect(lis(&v3, gpa.allocator()) == 3);

const v4 = [0]i32{};
try testing.expect(lis(&v4, gpa.allocator()) == 0);

const v5 = [5]i32{ 0, 0, 0, 0, 0 };
try testing.expect(lis(&v5, gpa.allocator()) == 1);
}
1 change: 1 addition & 0 deletions runall.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ rem Data Structures
rem Dynamic Programming
%ZIG_TEST% -Dalgorithm=dp/coinChange %Args%
%ZIG_TEST% -Dalgorithm=dp/knapsack %Args%
%ZIG_TEST% -Dalgorithm=dp/longestIncreasingSubsequence %Args%

rem Sort
%ZIG_TEST% -Dalgorithm=sort/quicksort %Args%
Expand Down
1 change: 1 addition & 0 deletions runall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ $ZIG_TEST -Dalgorithm=ds/lrucache $Args
# Dynamic Programming
$ZIG_TEST -Dalgorithm=dp/coinChange $Args
$ZIG_TEST -Dalgorithm=dp/knapsack $Args
$ZIG_TEST -Dalgorithm=dp/longestIncreasingSubsequence $Args

## Sort
$ZIG_TEST -Dalgorithm=sort/quicksort $Args
Expand Down
Loading