督促自己——Java算法题四道(某扣)——(深度优先搜索、回溯算法)

督促自己——Java算法题四道——(深度优先搜索、回溯算法)

第一题:——回溯算法(中)
给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:
board =
[
[‘A’,‘B’,‘C’,‘E’],
[‘S’,‘F’,‘C’,‘S’],
[‘A’,‘D’,‘E’,‘E’]
]
给定 word = “ABCCED”, 返回 true
给定 word = “SEE”, 返回 true
给定 word = “ABCB”, 返回 false
基本思路:对每一个点都进行一次搜索,也就意味着有多条路径,只需要注意每条路径内不走已经走过的点就行了,只要一条路径走完还没结果就return,继续递归下一条路。

class Solution {
    
    
    public boolean exist(char[][] board, String word) {
    
    
         for(int i=0;i<board.length;++i){
    
    
             for(int j=0;j<board[i].length;++j){
    
    
                if(myexist(board,0,word,i,j)){
    
    
                    return true;
                }
             }
         }
         return false;
    }
    public boolean myexist(char[][]board,int count,String word,int x,int y){
    
    
        if(count==word.length()){
    
    
            return true;
        }
          if(x<0||x>=board.length||y<0||y>=board[0].length||board[x][y]!=word.charAt(count)){
    
    
            return false;
          }
            board[x][y]='0';
          boolean flag=myexist(board,count+1,word,x+1,y)||myexist(board,count+1,word,x,y+1)||myexist(board,count+1,word,x,y-1)||myexist(board,count+1,word,x-1,y);
               board[x][y]=word.charAt(count);
            return flag;
    }
}

第二题:——回溯算法(中)
给定一个数字字符串 S,比如 S = “123456579”,我们可以将它分成斐波那契式的序列 [123, 456, 579]。
形式上,斐波那契式序列是一个非负整数列表 F,且满足:
0 <= F[i] <= 2^31 - 1,(也就是说,每个整数都符合 32 位有符号整数类型);
F.length >= 3;
对于所有的0 <= i < F.length - 2,都有 F[i] + F[i+1] = F[i+2] 成立。
另外,请注意,将字符串拆分成小块时,每个块的数字一定不要以零开头,除非这个块是数字 0 本身。
返回从 S 拆分出来的任意一组斐波那契式的序列块,如果不能拆分则返回 []。
示例 1:
输入:“123456579”
输出:[123,456,579]
示例 2:
输入: “11235813”
输出: [1,1,2,3,5,8,13]
示例 3:
输入: “112358130”
输出: []
解释: 这项任务无法完成。
基本思路:回溯思想,对所有可能的路依次递归遍历,直到找到第一个出现的斐波那契数列(此时必须字符串遍历完成,否则不作数)。如果结果不对,去除当前新插入顺序表中的数,回溯,进行下一条路的遍历。

class Solution {
    
    
    public List<Integer> splitIntoFibonacci(String S) {
    
    
         if(S==null||S.length()==0){
    
    
            return new ArrayList<>();
        }
            List<Integer>list=new ArrayList<>();
            splitInto(S,S,list,0);
            return list;
        }
    public boolean splitInto(String s,String S,List<Integer>list,int index){
    
    
         if(s==null||s.length()==0){
    
    
                if(S.length()==index&&list.size()>=3){
    
    
                 return true;
         }
         return false;
         }
        
        for(int i=0;i<s.length();++i){
    
    
            String str=s.substring(0,i+1);
            if(str.length()>1&&str.charAt(0)=='0'){
    
    
                break;
            } else{
    
    
               if(Long.valueOf(str)>Integer.MAX_VALUE){
    
    
                  break;
               }
                    int len=list.size();
               if(len>=2&&Integer.valueOf(str)>list.get(len-1)+list.get(len-2)){
    
    
                  break;
               }
                if(len<=1||list.get(len-1)+list.get(len-2)==Integer.valueOf(str)){
    
    
                    list.add(Integer.valueOf(str));
                     System.out.println(Integer.valueOf(str));
                    if(splitInto(s.substring(i+1,s.length()),S,list,index+str.length())){
    
    
                        return true;
                    }
                        list.remove(list.size()-1);
                }
            }
        }
        return false;
    }
    }

第三题:——深度优先搜索
有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。
省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。
给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。
返回矩阵中 省份 的数量。
基本思路:分别对每个省(i)进行判断,如果还未被访问过,就省份加加,递归附属省(i,j)。切记对访问过的省标记一下。

class Solution {
    
    
    int len=0;
    public int findCircleNum(int[][] isConnected) {
    
    
        for(int i=0;i<isConnected.length;++i){
    
    
            if(isConnected[i][i]>0){
    
    
                len++;
                 find(isConnected,i);
            }
        }
        return len;
    }
    public void find(int[][]isConnected,int i){
    
    
     if(i>=isConnected.length){
    
    
         return;
     } 
     isConnected[i][i]=-1;
     for(int j=0;j<isConnected[i].length;++j){
    
    
         if(isConnected[i][j]==1&&i!=j&&isConnected[i][j]>0){
    
    
             isConnected[i][j]=-1;
             isConnected[j][i]=-1;
             find(isConnected,j); 
         }
     }
    }
}

第四题:——深度优先搜索
给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字。
每条从根节点到叶节点的路径都代表一个数字:
例如,从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123 。
计算从根节点到叶节点生成的 所有数字之和 。
叶节点 是指没有子节点的节点。

在这里插入图片描述
例如:12+13=25,其中1->2,1->3分别是两条根到叶的路径。
基本思路:判断当前节点是否是叶子节点,是就连接然后,将当前路径入顺序表中,否则连接节点,递归即可;最后遍历顺序表,对每条路径转换求和即可。

class Solution {
    
    
    public int sumNumbers(TreeNode root) {
    
    
        List<String>list=new ArrayList<>();
        load(root,"",list);
        int sum=0;
        for(String s:list){
    
    
            sum+=Integer.parseInt(s);
        }
        return sum;
    }
    public void load(TreeNode root,String str,List<String>list){
    
    
        if(root==null){
    
    
           return;
        }
        if(root.left==null&&root.right==null){
    
    
            str+=(root.val+"");
            list.add(str);
            return;
        }
       str+=(root.val+"");
       load(root.left,str,list);
       load(root.right,str,list);
    }
}

今天状态不太好,写了好久,但是,坚持就是胜利!!!!!!!!!

猜你喜欢

转载自blog.csdn.net/qq_45841205/article/details/115409151