获取java中矩阵中连续出现k次的所有数字

Posted

技术标签:

【中文标题】获取java中矩阵中连续出现k次的所有数字【英文标题】:Get all numbers that appears k times consecutively in a matrix in java 【发布时间】:2020-08-31 22:45:32 【问题描述】:

这是我的previous question 的更多详细信息,因为它被标记为已关闭。

我有一个大小为nxn 的矩阵,现在我想找到一个连续出现 k 次的数字(上、下、左、右、对角线)。如果找到数字则返回,否则返回 0。如果有多个数字出现 k 次,则按升序返回所有数字。

Example:

Given matrix:

3 5 3 9 5
4 3 2 1 8
9 4 3 1 9
8 4 7 6 4
1 2 5 9 1

Given k = 3

Output: number 3. Because only number 3 is occurring 3 times in diagonal way.

如何在 Java 编程中编写此逻辑。你能给出一些想法,以便我可以从那里继续吗? 公共静态无效主要(字符串[]参数) int[][] m = 3, 5, 3, 9, 5 , 4, 3, 2, 1, 8 , 9, 4, 3, 1, 9 , 8, 4, 7 , 6, 4 , 1, 2, 5, 9, 1 ; int k = 3;

    List<Integer> result = process(m, k);
    System.out.println(result);


private static List<Integer> process(int[][] m, int k) 
    List<Integer> result = new ArrayList<>();
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < m.length; i++) 
        for (int j = 0; j < m.length; j++) 
            int count = map.getOrDefault(m[i][j], 0);
            map.put(m[i][j], count + 1);
        
    

    for (int number : map.keySet()) 
        if (map.get(number) >= k) 
            int consecutiveCount = getConsecutiveCount(number, m, k);
            if (consecutiveCount >= k) 
                result.add(number);
            
        
    
    if (result.size() == 0) 
        result.add(-1);
    
    return result;


private static int getConsecutiveCount(int number, int[][] m, int k) 
    return 0;

这里如何实现getConsecutiveCount逻辑?

更新:

尝试使用以下代码使用 DFS 进一步导航相邻节点,但计数无法正常工作,它仅显示数字在矩阵中出现的次数:

static boolean isSafe(int M[][], int row, int col, boolean visited[][], int number) 
    int ROW = M.length;
    int COL = M[0].length;
    return (row >= 0) && (row < ROW) && (col >= 0) && (col < COL) && (M[row][col] == number && !visited[row][col]);


static void DFS(int M[][], int row, int col, boolean visited[][], int number, int[] total) 
    int rowNbr[] = new int[] -1, 1, 0, 1, 1;
    int colNbr[] = new int[] 0, 0, -1, 0, 1;

    visited[row][col] = true;
    total[0]++;
    for (int k = 0; k < rowNbr.length; ++k)
        if (isSafe(M, row + rowNbr[k], col + colNbr[k], visited, number)) 
            DFS(M, row + rowNbr[k], col + colNbr[k], visited, number, total);
        


static int countIslands(int M[][], int number) 
    int ROW = M.length;
    int COL = M[0].length;
    boolean visited[][] = new boolean[ROW][COL];

    int count = 0;
    int[] total = 0;
    for (int i = 0; i < ROW; ++i)
        for (int j = 0; j < COL; ++j)
            if (M[i][j] == number && !visited[i][j]) // If a cell with
             
                DFS(M, i, j, visited, number, total);
                ++count;
            

    return total[0];


// Driver method
public static void main(String[] args) throws java.lang.Exception 
    int M[][] = new int[][]   3, 5, 3, 9, 5 ,  4, 3, 2, 1, 8 ,  9, 4, 3, 1, 9 ,  8, 4, 7, 6, 4 ,
             1, 2, 5, 9, 1  ;
    List<Integer> result = process(M, 3);
    System.out.println(result);


private static List<Integer> process(int[][] m, int k) 
    List<Integer> result = new ArrayList<>();
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < m.length; i++) 
        for (int j = 0; j < m.length; j++) 
            int count = map.getOrDefault(m[i][j], 0);
            map.put(m[i][j], count + 1);
        
    
    System.out.println(map);

    for (int number : map.keySet()) 
        if (map.get(number) >= k) 
            int consecutiveCount = getConsecutiveCount(number, m, k);
            System.out.println(number + " : " + consecutiveCount);
            if (consecutiveCount >= k) 
                result.add(number);
            
        
    
    if (result.size() == 0) 
        result.add(-1);
    
    return result;


private static int getConsecutiveCount(int number, int[][] m, int k) 
    return countIslands(m, number);

【问题讨论】:

您之前的问题已关闭,因为您没有说明您在尝试自己实施时遇到的问题。它需要更多的关注,一个具体的问题。你基本上所做的只是发布你的作业。 您可以编辑问题...这些 cmets 上方有一个链接,位于您的名片左侧。您应该编辑旧问题并删除此问题,或者删除此问题并编辑旧问题。编辑可能是更好的解决方案,因为它可以让您有机会删除它收到的反对票。仔细考虑你的编辑,因为看起来你在这个问题上犯的错误与你在原始问题中犯的错误一样。如果您不确定,请阅读how to ask。 @Dioxin,我现在添加了使用 DFS 方法的代码,但在如何导航和获取计数上卡住了。 因此,DFS 并不是完全正确的方法,因为您并没有真正的搜索“结束”。如果所有元素都相同,我将创建一个接受大小为 K 的数组的方法,该数组返回 true。然后,我将使用x = 0 &lt; x &lt; N-Ky = 0 &lt; y &lt; N-K 在 K 大小(左、下、右下、左下)的部分中循环矩阵 M。甚至可能将每个矩阵扫描方向分解为自己的方法。我认为您不需要布尔矩阵,但可能需要 TreeMap&lt;Integer, Integer&gt; 来“按升序”存储数据 你能再给一个测试用例吗 【参考方案1】:

无需实际为您编写此代码,我会为您指明正确的方向。这个想法是将问题分成更小的问题,直到你得到一些小问题。

所以这样想:

    n * n 可能的起始位置。因此,可以将其视为行和列上的一对外部嵌套循环:y 从 0 到 nx 从 0 到 n。 对于每个起始位置x,y,您的序列有 8 个不同的方向。将它们想象成两个嵌套循环:dx 超过 -1 到 1 和 dy 超过 -1 到 1(但 dxdy 不都是 0)。 对于任何起始位置xy(其中0xn和0yn,方向向量dxdx, (其中dxdy分别是-101但都不是0),你可以找出如果通过将值m[x][y] 与每个值m[x+dx*i][y+dy*i] 进行比较,存在长度为k 的重复序列,对于i 的值在0k 之间。(所以那里还有另一个循环。)

这就是整个算法。

现在进行一些简化和边界约束:

    由于重复序列根据定义是回文序列(向后与向前相同),因此您只需考虑这八个方向中的四个。例如:(0, 1), (1, 0), (1, 1), (-1, 1)。 不要尝试读取索引超出范围的任何矩阵值。

编码愉快!

【讨论】:

我根据你的cmets添加了我的尝试,但又卡住了,你能检查一下吗 其实有(n-k) * (n-k)的起始位置。否则,您会多次找到相同的序列(向前和向后)。如果你限制于此,那么向量只有 (0,1)、(1, 0)、(1,1),而且你永远不会“越界” 这就是为什么您只想查看八个方向中的四个。 (见我对回文的评论) 你能写代码吗?【参考方案2】:
input1 = int(input())  # 5
input2 = input()  # '  3, 5, 3, 9, 5 ,  4, 3, 2, 1, 8 ,  9, 4, 3, 1, 9 ,  8, 4, 7, 6, 4 ,  1, 2, 5, 9, 1  '
input3 = int(input())  # 3
digits = [int(i) for i in input2 if i.isdigit()]
reformatted_input2 = [digits[:i+1][-5:] for i in range(len(digits)) if (i + 1) % 5 == 0]
indexes = [i.index(input3) for i in reformatted_input2 if input3 in i]
if indexes == list(range(min(indexes), max(indexes) + 1)):
    print(len(indexes))
else:
    print(-1)

【讨论】:

以上是关于获取java中矩阵中连续出现k次的所有数字的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode--SQL 查询:查找所有至少连续出现三次的数字。

180. 连续出现的数字

用java编写一个字符串的程序,找出连续出现三次的字符

Lc180-连续出现的数字

sql 180. 连续出现的数字

[LeetCode]刷题---连续出现的数字