dengxinyi 6 lat temu
rodzic
commit
a5985129db
2 zmienionych plików z 112 dodań i 1 usunięć
  1. 37 1
      hard/335.self-crossing.go
  2. 75 0
      hard/336.palindrome-pairs.go

+ 37 - 1
hard/335.self-crossing.go

@@ -1,4 +1,40 @@
 func isSelfCrossing(x []int) bool {
-	
+	// 3 situations for self crossing:
+	// 1.     _____    0 intersects 3, x[2] <= x[0] && x[1] <= x[3]
+	//       |  1  |
+	//      2|     |0
+	//       `-----+-
+	//          3  |
+	//
+	// 2.    _____     0 intersects (and coincides) 4,
+	//      |  1  |    x[1] == x[3] && x[2] <= x[0] + x[4]
+	//     2|     |0
+	//      |     |
+	//      |_____^4
+	//         3
+	//
+	// 3.    ___       0 intersects 5,
+	//      | 1 |  5   x[4] <= x[2] && x[1] <= x[3] && x[2] <= x[0] + x[4] && x[3] <= x[1] + x[5]
+	//      | <-+---.
+	//     2|   |0  |4
+	//      |_______|
+	//          3
+	//
+	n := len(x)
+	if n < 4 {
+		return false
+	}
+	for i := 3; i < n; i++ {
+		if x[i-1] <= x[i-3] && x[i-2] <= x[i] {
+			return true
+		}
+		if 4 <= i && x[i-3] == x[i-1] && x[i-2] <= x[i-4]+x[i] {
+			return true
+		}
+		if 5 <= i && x[i-1] <= x[i-3] && x[i-4] <= x[i-2] && x[i-3] <= x[i-5]+x[i-1] && x[i-2] <= x[i-4]+x[i] {
+			return true
+		}
+	}
+	return false
 }
 

+ 75 - 0
hard/336.palindrome-pairs.go

@@ -0,0 +1,75 @@
+func palindromePairs(words []string) (res [][]int) {
+	m := make(map[string]int)
+	n := len(words)
+	for i := 0; i < n; i++ {
+		k := len(words[i])
+		runes := make([]rune, k)
+		for _, r := range words[i] {
+			k--
+			runes[k] = r
+		}
+		m[string(runes)] = i
+	}
+	for i := 0; i < n; i++ {
+		if idx, ok := m[""]; ok && idx != i && isPalindrome(words[i]) {
+			res = append(res, []int{idx, i}) // Empty string and palindrome
+			res = append(res, []int{i, idx})
+		}
+		if idx, ok := m[words[i]]; ok && idx != i {
+			res = append(res, []int{idx, i}) // Whole string and its reverse
+		}
+		k := len(words[i])
+		for j := 1; j < k; j++ {
+			wl, wr := words[i][:j], words[i][j:]
+			if idx, ok := m[wr]; ok && isPalindrome(wl) { // wr' + wl + wr
+				res = append(res, []int{idx, i})
+			}
+			if idx, ok := m[wl]; ok && isPalindrome(wr) { // wl + wr + wl'
+				res = append(res, []int{i, idx})
+			}
+		}
+	}
+	return
+}
+
+func isPalindrome(s string) bool {
+	n := len(s)
+	for l, r := 0, n-1; l < r; l, r = l+1, r-1 {
+		if s[l] != s[r] {
+			return false
+		}
+	}
+	return true
+}
+
+func palindromePairsOn3(words []string) (res [][]int) { // Brute search, O(n^3)
+	n := len(words)
+	for i := 0; i < n-1; i++ {
+		for j := i + 1; j < n; j++ {
+			b1, b2 := isPalindromePair(words[i], words[j])
+			if b1 {
+				res = append(res, []int{i, j})
+			}
+			if b2 {
+				res = append(res, []int{j, i})
+			}
+		}
+	}
+	return
+}
+
+func isPalindromePair(s1, s2 string) (bool, bool) {
+	s12, s21 := s1+s2, s2+s1
+	n := len(s12)
+	b1, b2 := true, true
+	for l, r := 0, n-1; l < r && (b1 || b2); l, r = l+1, r-1 {
+		if s12[l] != s12[r] {
+			b1 = false
+		}
+		if s21[l] != s21[r] {
+			b2 = false
+		}
+	}
+	return b1, b2
+}
+