Skip to content

Commit 6f0450c

Browse files
committed
add solution for exercise3-18
1 parent d74cfb0 commit 6f0450c

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

chapter3/exercise3-18.rkt

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#lang racket
2+
;;; 支持 mutable 与 immutable
3+
4+
;;; 时间复杂度 O(N), 空间复杂度 O(N)
5+
(define (memo-has-circle? x)
6+
(let ((seen '()))
7+
(define (iter lst)
8+
(cond
9+
((and (not (pair? lst)) (not (mpair? lst))
10+
#f))
11+
((memq lst seen)
12+
#t)
13+
(else
14+
(set! seen (cons lst seen))
15+
(match lst
16+
[ (cons a b) (iter b)]
17+
[ (mcons a b) (iter b)]
18+
[_ #f])
19+
)))
20+
(iter x)))
21+
22+
;;; 双指针方案
23+
;;; 时间复杂度 O(N), 空间复杂度 O(1)
24+
(define (has-circle? x)
25+
(define (safe-cdr lst)
26+
(cond ((pair? lst)
27+
(cdr lst))
28+
((mpair? lst)
29+
(mcdr lst))
30+
(else '())))
31+
32+
(define (is-pair? lst)
33+
(or (pair? lst) (mpair? lst)))
34+
35+
(let loop ((tortoise x)
36+
(hare (safe-cdr x)))
37+
(cond ((or (not (is-pair? tortoise))
38+
(not (is-pair? hare))
39+
(not (is-pair? (safe-cdr hare))))
40+
#f)
41+
((eq? tortoise hare)
42+
#t)
43+
(else
44+
(loop (safe-cdr tortoise)
45+
(safe-cdr (safe-cdr hare))))
46+
))
47+
)
48+
49+
(module+ test
50+
(require rackunit)
51+
(test-case "Test for circular? with circular mutable list"
52+
(define cycle (mcons 1 (mcons 2 null)))
53+
(set-mcdr! (mcdr cycle) cycle)
54+
(check-true (memo-has-circle? cycle))
55+
(check-true (has-circle? cycle)))
56+
(test-case "Test for circular? with non-circular mutable list"
57+
(define non-cycle (mcons 1 (mcons 2 null)))
58+
(check-false (memo-has-circle? non-cycle))
59+
(check-false (has-circle? non-cycle)))
60+
61+
(test-case "Test for circular? with immutable list"
62+
(define imm-list (list 1 2 3))
63+
(check-false (memo-has-circle? imm-list))
64+
(check-false (has-circle? imm-list)))
65+
)

0 commit comments

Comments
 (0)