You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
3.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class009;
import java.util.ArrayList;
import java.util.List;
public class Code03_LongestOnes {
public static List<Integer> longestOnes1(int[][] matrix) {
int N = matrix.length;
int M = matrix[0].length;
List<Integer> ans = new ArrayList<>();
int maxLen = 0;
for (int i = 0; i < N; i++) { // 每一行的答案i
int j = M; // 最左发现的1的位置
while (j > 0 && matrix[i][j - 1] == 1) {
j--;
}
if (maxLen < M - j) {
maxLen = M - j;
ans.clear();
}
if (maxLen == M - j) {
ans.add(i);
}
}
return ans;
}
public static List<Integer> longestOnes2(int[][] matrix) {
int N = matrix.length;
int M = matrix[0].length;
List<Integer> ans = new ArrayList<>();
int maxLen = 0;
int col = M;
for (int i = 0; i < N; i++) {
while (col > 0 && matrix[i][col - 1] == 1) {
col--;
}
// col来到当前i行最左侧的1的位置
if (maxLen < M - col) {
maxLen = M - col;
ans.clear();
}
if (matrix[i][col] == 1) {
ans.add(i);
}
}
return ans;
}
public static List<Integer> longestOnes3(int[][] matrix) {
int N = matrix.length;
int M = matrix[0].length;
List<Integer> ans = new ArrayList<>();
int maxLen = 0;
for (int i = 0; i < N; i++) {
int j = mostLeftOne(matrix[i], 0, M - 1);
if (maxLen < M - j) {
maxLen = M - j;
ans.clear();
}
if (maxLen == M - j) {
ans.add(i);
}
}
return ans;
}
public static List<Integer> longestOnes4(int[][] matrix) {
int N = matrix.length;
int M = matrix[0].length;
List<Integer> ans = new ArrayList<>();
int maxLen = 0;
int col = M;
for (int i = 0; i < N; i++) {
col = mostLeftOne(matrix[i], 0, col - 1);
if (maxLen < M - col) {
maxLen = M - col;
ans.clear();
}
if (matrix[i][col] == 1) {
ans.add(i);
}
}
return ans;
}
// arr[L..R]上一定有一个前期要么都是0要么都是1如果0和1都有0在左侧1在右侧
public static int mostLeftOne(int[] arr, int L, int R) {
int ans = R + 1; // R + 1 -> [L..R] 没有1的
int M = 0;
while (L <= R) {
M = (L + R) / 2;
if (arr[M] == 1) {
ans = M;
R = M - 1;
} else {
L = M + 1;
}
}
return ans;
}
// for test
// 随机生成一个最大规模达到rowSize * colSize的矩阵
// 确保每一行都是0在左侧1在右侧
public static int[][] generateRandomMatrix(int rowSize, int colSize) {
int N = (int) (Math.random() * rowSize) + 1;
int M = (int) (Math.random() * colSize) + 1;
int[][] matrix = new int[N][M];
for (int i = 0; i < N; i++) {
int[] arr = new int[M];
int rightStart = (int) (Math.random() * M);
for (int j = rightStart; j < M; j++) {
arr[j] = 1;
}
matrix[i] = arr;
}
return matrix;
}
public static boolean equal(List<Integer> ans1, List<Integer> ans2) {
if (ans1.size() != ans2.size()) {
return false;
}
int N = ans1.size();
for (int i = 0; i < N; i++) {
if (!ans1.get(i).equals(ans2.get(i))) {
return false;
}
}
return true;
}
public static void main(String[] args) {
System.out.println("Hello!");
int rowSize = 30;
int colSize = 100;
int testTimes = 300000;
System.out.println("test begin");
for (int i = 0; i < testTimes; i++) {
int[][] matrix = generateRandomMatrix(rowSize, colSize);
List<Integer> ans1 = longestOnes1(matrix);
List<Integer> ans2 = longestOnes2(matrix);
List<Integer> ans3 = longestOnes3(matrix);
List<Integer> ans4 = longestOnes4(matrix);
if (!equal(ans1, ans2) || !equal(ans3, ans4) || !equal(ans1, ans3)) {
System.out.println("Oops");
}
}
System.out.println("test end");
}
}