-
-
Notifications
You must be signed in to change notification settings - Fork 63
Expand file tree
/
Copy pathlongestIncreasingSubsequence.zig
More file actions
68 lines (54 loc) · 1.75 KB
/
longestIncreasingSubsequence.zig
File metadata and controls
68 lines (54 loc) · 1.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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 lowerBound(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) = .empty;
defer v.deinit(allocator);
const n = arr.len;
for (0..n) |i| {
const it = lowerBound(v.items, arr[i]);
if (it == v.items.len) {
_ = v.append(allocator, 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);
}