数据结构入门

数据结构入门

第一天内容:

第一题,存在重复元素

 这一道题的思路是通过前一个的length()和它用hashSet存储之后的length()的结果进行对比,如果相等,说明了一件事情,这个里面不包含重复元素,如果不相等说明,有重复元素

具体代码如下:

class Solution {
    public boolean containsDuplicate(int[] nums) {
//分析题目:
//首先如果全部不相同,返回false
//而只要出现了一个值拥有两个或两个以上返回true
//两个for循环不能通过
      Set<Integer> Set = new HashSet<Integer>();
      for(int i:nums) {
         Set.add(i); 
      }
      return Set.size()<nums.length?true:false;

    }
}

第二题,最大子数组和

分析,它需要的是求和,求和需要满足 的条件,他的结果必须得是一个正数,它不能加着加着变成了负数,所以可以判断一个条件,如果这个值的和已经开始变成负数了,就开始进行下一个。所以我们可以使用递归的方法来进行求和的操作。

 代码段

class Solution {
    public int maxSubArray(int[] nums) {
        int res = nums[0];//第一个值
        int sum = 0;//求和设置的一个变量
        for(int num: nums) {//遍历的方式
            if(sum >0) {//首先要保证前面的和是大于0的
//原因是因为这个sum的值不可能是小于0的
                sum +=num;
            }else{
                sum = num;//新的开始
            }
            res = Math.max(res,sum);//比较最大值
/**
比较一下值,最后确定所得到的值的大小,和上一个记录的sum的值进行比较,得到结果。
*/
        }
        return res;
    }
}

第二天内容

第一题,两数之和

 两种方法:

第一种:暴力破解

第二种:用HashMap的方法:containKey

class Solution {
    public int[] twoSum(int[] nums, int target) {
        //  int i;
        //  int [] num = new int[2];
         //用的是暴力破解法
        /* for(int j= 0;j<nums.length-1;j++) {
             for(int z=j+1;z<=nums.length-1;z++) {
                 if(nums[j]+nums[z] == target) {
                     num[0] = j;
                     num[1] = z;
                     return num;
                 }
             }
         }*/
         //时间复杂度变小的方法,哈希数
          Map<Integer, Integer> map = new HashMap<>();
         for(int i = 0; i< nums.length; i++) {
            if(map.containsKey(target - nums[i])) {
                return new int[] {map.get(target-nums[i]),i};
            }
            map.put(nums[i], i);
        }
        throw new IllegalArgumentException("No two sum solution");
    }
}

第二题,合并两个有序数组

, 分析:

两个有序数组合并之后,还是以递归的方式。所以可以先比较每一个数组的第一个值,谁小谁就第一位,之后再进行下一位和上一个没有进新的数组的里面的哪一个

代码段

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        //首先明白两个非递减顺序合并的是一个新的非递减顺序,说明合成的是一个递增的序列
        int i = m - 1, j = n - 1, k = m + n - 1;
        while (j >= 0) {
            if (i < 0 || nums2[j] > nums1[i]) {
                nums1[k--] = nums2[j--];
            } else {
                nums1[k--] = nums1[i--];
            }
          //  nums1[k--]=nums2[j]>nums1[i]||i<0?nums2[j--]:nums1[i--];
        } 
    }
}

第三题 ,整数反转。

分析;就是将数字倒过来。,如果是负数,先把负号放在最前面,再进行反转

代码段

class Solution {
    public int reverse(int x) {
        
        if(x==0) {
            return 0;

        }
        int y=x>0?x:-x;//此时y代表的值是x的绝对值;
        int num;
        int res=0;
       while(y!=0) {
           num = y%10;//最尾部的数
           int temp = res;
           res = res*10 + num;
           y = y/10;
           if(res/10!=temp) {
               return 0;
           }
       }
      
       return x>0?res:-res;

    }
}

第三天内容

第一题,两个数组的交集 

分析题目可以知道,这道题所要求的是两个数组中里面一样的值,将它弄在新的数组里面。

代码段

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
            if(nums1.length>nums2.length) {
                return intersect(nums2 , nums1);
            }

            int [] jieguo = new int [nums1.length];
             Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int num : nums1) {
            int count = map.getOrDefault(num, 0) + 1;
            map.put(num, count);
        }       
        int index = 0;
        for (int num : nums2) {
            int count = map.getOrDefault(num, 0);
            if (count > 0) {
                jieguo[index] = num;
                index++;
                count--;
                if (count > 0) {
                    map.put(num, count);
                } else {
                    map.remove(num);
                }
            }
        }
        return Arrays.copyOfRange(jieguo, 0, index);
    }
}

第二题,买卖股票的最佳时机

 首先要确定的一件事情,就是它所买的时候的价格一定要比卖的时候低

代码段

class Solution {
    public int maxProfit(int[] prices) {
       if(prices.length<=1) {
           return 0;
       }
       int min=prices[0],max=0;
        for(int i=1;i<prices.length;i++) {
            //max = Math.max(max, prices[i] - min);
            max = max>(prices[i]-min)?max:prices[i]-min;
           // min = Math.min(min, prices[i]);
           min=min>prices[i]?prices[i]:min;
        }
        return max;
    }
}

第四天内容

第一题,重塑矩阵

 分析:

首先:第一步需要判断矩阵的元素有没有变化。

再进行输出

代码段:

class Solution {
    public int[][] matrixReshape(int[][] mat, int r, int c) {
        int m = mat.length;
        int n = mat[0].length;
        if (m * n != r * c) {
            return mat;
        }

        int[][] ans = new int[r][c];
        for (int x = 0; x < m * n; ++x) {
            ans[x/c][x%c]=mat[x / n][x % n];
        }
        return ans;
    }
}

第二题,杨辉三角

分析:

把图形分解一下

1

11

121

1331

14641

....

可以得到一个结论

它的第一行的数都是1

每一行最后一个都是1

每一个中间的值,都等于上一行的和这这一列相同的位置,和前一个位置的和

代码段:

class Solution {
    public List<List<Integer>> generate(int numRows) {
         List<List<Integer>> list = new ArrayList<>();
        int[][] arr = new int [numRows][numRows];
        for(int i=0;i<numRows;i++) {
            List<Integer> zhongjian = new ArrayList<>();
            for(int j=0;j<=i;j++) {
                if(j==0||j==i) {
                    arr[i][j]=1;
                }else{
                    arr[i][j]=arr[i-1][j-1]+arr[i-1][j];
                }
                zhongjian.add(arr[i][j]);
            }
            list.add(zhongjian);
        }
        return list;
    }
}

 第五天

第一题,有效的数独

 分析:

用HashSet,因为HashSet不能存储相同的元素。

代码段

class Solution {
    public boolean isValidSudoku(char[][] board) {
            Set<Character> row = new HashSet<>();
            Set<Character> col = new HashSet<>();
            Set<Character> jiugunge = new HashSet<>();
            for (int i = 0; i < 9; i++) {
                for (int j = 0; j < 9; j++) {
                    
                    if (board[j][i] != '.' && !row.add(board[j][i]))
                        return false;
                    
                    if (board[i][j] != '.' && !col.add(board[i][j]))
                        return false;
                    
                    if (board[i % 3 * 3 + j / 3][i / 3 * 3 + j % 3] != '.' && !jiugunge.add(board[i % 3 * 3 + j / 3][i / 3 * 3 + j % 3]))
                        return false;

                }
                row.clear();
                col.clear();
                jiugunge.clear();
            }
            return true;
    }
}

第二题,矩阵清零

 这一道题,我最开始的思路是正确的,但是就是做不出来,因为没有考虑到如果一次判断这一个为0那么这一行就为0的时候,当进行到下一行也会变成0,最后就会导致出现错误。出现整个数组全为0的情况。最后我实在想不出来了的时候,这个时候我就去看了一下参考答案。

它的思路就是,如果出现了将每一行每一列重新设置为一个Boolean类型,如果出现了为0的情况,就将该值返回为true,如果没有出现的话就返回false。最后执行到后面,再次做一个循环,如果它的行中满足某一个值为0,则哪一行的所有值都为0,同时为0的那个值,它所在的那一列也会变成都为0

class Solution {
    public void setZeroes(int[][] matrix) {
        // int[][] arr = new int[matrix.length][matrix[0].length];
        // //这个函数记录的是matrix的包含0的数据;
        // for(int i=0;i<matrix.length;i++) {//这里是执行的循环
            
        //     int m=0;
        //     int n=0;
        //     for(int j=0;j<matrix[0].length;j++) {
        //         if(matrix[i][j]==0){
        //             m=i;n=j;
        //             matrix[i][j]=arr[m][n]=0;
        //         }
        //     }
        // }
        //  for(int i=0;i<matrix.length;i++) {//这里是执行的循环
        //     for(int j=0;j<matrix[0].length;j++) {
        //         if(arr[i][j]==0){
        //             arr[i][0]=0;
        //             arr[0][j]=0;
        //         }
        //     }
        // }
        //  for(int i=0;i<matrix.length;i++) {//这里是执行的循环
        //     for(int j=0;j<matrix[0].length;j++) {
        //         if(arr[i][j]!=0){
        //            arr[i][j]=matrix[i][j];
        //         }
        //     }
        // }
        // for(int i=0;i<matrix.length;i++) {//这里是执行的循环
        //     for(int j=0;j<matrix[0].length;j++) {
        //         matrix[i][j]=arr[i][j];
        //     }
        // }
         int m = matrix.length, n = matrix[0].length;
        boolean[] row = new boolean[m];
        boolean[] col = new boolean[n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == 0) {
                    row[i] = col[j] = true;
                }
            }
        }
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (row[i] || col[j]) {
                    matrix[i][j] = 0;
                }
            }
        }


    }
}

第六天

第一题,赎金信

 分析:

如果magazine中包含ransomNote里面的所有的元素,就会返回true,否则返回false;

最开始我是想用subString()这个方法的,但是后来才发现用这个方法会报错,我也不知道这是为什么,然后我就去看了答案,以为它也是用的subString方法,后来发现并不是,它用的是Ascll码的方式,我去看评论也没有看到有人用subString方法。由于看了答案,所以我就去用了它的源码了。

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
    //    int m= ransomNote.length();
    //    int n= magazine.length();
    //    if(m>n) {
    //        return false;
    //    }else{
    //        for(int i=1;i<n-m;i++) {
    //            if(ransomNote.equal(magazine.subString(i,m))){
    //                return true;
    //            }
    //            m++;
    //        }
    //    }
     int[] arr = new int[26];
        int temp;
        for (int i = 0; i < magazine.length(); i++) {
            temp = magazine.charAt(i) - 'a';
            arr[temp]++;
        }
        for (int i = 0; i < ransomNote.length(); i++) {
            temp = ransomNote.charAt(i) - 'a';
            //对于金信中的每一个字符都在数组中查找
            //找到相应位减一,否则找不到返回false
            if (arr[temp] > 0) {
                arr[temp]--;
            } else {
                return false;
            }
        }
        return true;
    }
}

第二题,有效的字母异位词 

分析:异位词,说明它里面包含的字母是相同的

所以第一步,判断它们的字符长度是否相等,如果相等,就进行比较它们里面的字符是否是一致的。如果都有,说明了一件事情,说明了这个字符是字母异位词。

代码段:

class Solution {
    public boolean isAnagram(String s, String t) {
            if(s.length()!=t.length()){
                return false;
            }else{
                char[] str1 = s.toCharArray();
                char[] str2 = t.toCharArray();
                Arrays.sort(str1);
                Arrays.sort(str2);
                return Arrays.equals(str1, str2);
            }
    }
}

 

第七天

第一题,字符串的第一个唯一字符

 分析:

如果出现了一个字符,里面全是AABB这样有重复的元素,就说明了它是一个重复的字符,此时就会返回-1,如果里面的字符是这种AACBB这样类似的题目。

代码段

class Solution {
    public int firstUniqChar(String s) {
        for(int i=0; i<s.length(); i++){
            int first = s.indexOf(s.charAt(i));
            int last = s.lastIndexOf(s.charAt(i));
            if(first ==  last){
                return i;
            }
        }
        return -1;
    }
}

第二题,环形链表 

分析:题目中的第一句话中给出的如果链表中有某个节点,可以通过连续跟踪next指针再次到达

这道题最开始很难理解这个next的含义,后来我去看了一下它的答案,分析了一下,才想明白,它的含义就是

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
//注意里面有一个情况
        Set<ListNode> set = new HashSet<ListNode>();
        while(head!=null) {
            if(!set.add(head.next)) {
               return true;
            }head = head.next;
                
        }
        return false;
    }
}

第八天

第一题,合并两个有序数组

 分析:

两个升序链表结合成新的一个,这个前面有一道类似的题

所以直接给代码段

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode prehead = new ListNode(-1);
        ListNode prev = prehead;
        while(list1!=null && list2!=null) {
             if(list1.val<=list2.val) {
                 prev.next = list1;
                 list1=list1.next;
             }else{
                prev.next = list2;
                list2=list2.next;
             }
             prev = prev.next;
        }
        prev.next = list1 == null ? list2 : list1;
        return prehead.next;
    }
}

第二题,移除链表元素

 分析,只需要将里面中含有val的值的数变为null,可以直接得到结果。

代码段

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        // ListNode p =new ListNode(-1);
        
        // while(head!=null) {
        //     if(head.val==val){
        //         p.next=head.next;
        //         head = head.next;
        //     }else{
        //         p.add(head.val);
        //     }
        // }
        // return p.next;
         if (head == null) {
            return head;
        }
        head.next = removeElements(head.next, val);
        return head.val == val ? head.next : head;
    }
}

第九天

第一题,反转链表

 反转链表就是将原来的链表倒过来,

代码段

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null; //前指针节点
        ListNode curr = head; //当前指针节点
        //每次循环,都将当前节点指向它前面的节点,然后当前节点和前节点后移
        while (curr != null) {
            ListNode nextTemp = curr.next; //临时节点,暂存当前节点的下一节点,用于后移
            curr.next = prev; //将当前节点指向它前面的节点
            prev = curr; //前指针后移
            curr = nextTemp; //当前指针后移
        }
        return prev;
        // ListNode ans = null;
        // for (ListNode x = head; x != null; x = x.next) {
        //     ans = new ListNode(x.val,ans);
        // }
        // return ans;
    }
}

第二题,删除排序链表中的重复元素 

 分析:如果出现相等的,直接进行下一个

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
            if (head == null) {
                    return head;
                }

                ListNode cur = head;
                while (cur.next != null) {
                    if (cur.val == cur.next.val) {
                        cur.next = cur.next.next;
                    } else {
                        cur = cur.next;
                    }
                }

                return head; 
    }
}

第十天

第一题,有效的括号

, 分析:这道题的解法可以

代码段

class Solution {
    public boolean isValid(String s) {
         int n = s.length();
            if (n % 2 == 1) {
            return false;
        }

        Map<Character, Character> pairs = new HashMap<Character, Character>() {{
            put(')', '(');
            put(']', '[');
            put('}', '{');
        }};
        Deque<Character> stack = new LinkedList<Character>();
        for (int i = 0; i < n; i++) {
            char ch = s.charAt(i);
            if (pairs.containsKey(ch)) {
                if (stack.isEmpty() || stack.peek() != pairs.get(ch)) {
                    return false;
                }
                stack.pop();
            } else {
                stack.push(ch);
            }
        }
        return stack.isEmpty();


    }
}

第二题,用栈实现队列

 说实话,这道题我是真的不怎么会,我想了一会儿,写出来一个编译错误。

这里是答案

class MyQueue {
   Deque<Integer> inStack;
    Deque<Integer> outStack;

    public MyQueue() {
        inStack = new LinkedList<Integer>();
        outStack = new LinkedList<Integer>();
    }
    
    public void push(int x) {
        inStack.push(x);
    }
    
    public int pop() {
        if (outStack.isEmpty()) {
            in2out();
        }
        return outStack.pop();
    }
    
    public int peek() {
        if (outStack.isEmpty()) {
            in2out();
        }
        return outStack.peek();
    }
    
    public boolean empty() {
        return inStack.isEmpty() && outStack.isEmpty();
    }

    private void in2out() {
        while (!inStack.isEmpty()) {
            outStack.push(inStack.pop());
        }
    }
}

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();//返回队列开头的元素
 * boolean param_4 = obj.empty();//如果队列为空返回true
 */

第十一天

第一题,二叉树的前序遍历

 分析:这个太简单了,不用分析了

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    /**
    *
    
     */
    public List<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> res = new ArrayList<>();
        if (root ==null) return res;

        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);

        while (!stack.isEmpty()) {
            TreeNode curr = stack.pop();
            res.add(curr.val);
            if (curr.right != null) stack.push(curr.right);
            if (curr.left != null) stack.push(curr.left);
        }
        return res;


    }
}

第二题,中序遍历

 

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        Stack<TreeNode> stack = new Stack<>();
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            res.add(root.val);
            root = root.right;
        }
        return res;



    }
}

第三天 ,后序遍历

 

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
         List<Integer> res = new ArrayList<Integer>();
        Stack<TreeNode> stack = new Stack<>();TreeNode prev = null;
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
             
            root = stack.pop();
             if (root.right == null || root.right == prev) {
                res.add(root.val);
                prev = root;
                root = null;
            } else {
                stack.push(root);
                root = root.right;
            }


        }
        return res;


    }
}

第十二天

第一题,二叉数的层序遍历 

 分析:

输出结果是一个嵌套的数组集合,说明要定义两个数组。

分析临界值,如果出现null的情况,会返回什么,先进行调试测试一下。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
         List<List<Integer>> lists = new ArrayList<>();
        if (root == null) {
            return lists;
        }
        List<TreeNode> node = new ArrayList<>();
        node.add(root);
        while (!node.isEmpty()) {
            int size = node.size();
            List<Integer> list = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                TreeNode remove = node.remove(0);
                list.add(remove.val);
                if (remove.left != null) {
                    node.add(remove.left);
                }
                if (remove.right != null) {
                    node.add(remove.right);
                }
            }
            lists.add(list);
        }
        return lists;
    }
}

第二题,二叉树的最大深度

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
          if (root == null) {
            return 0;
        } else {
            int leftHeight = maxDepth(root.left);
            int rightHeight = maxDepth(root.right);
            return Math.max(leftHeight, rightHeight) + 1;
        }


    }
}

第三题,对称二叉树

 分析:最开始我没有想到用递归的思路,直到后来,才发现递归的方式要更简单,更好。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    /** 
    *首先注意节点的范围是在【1,100】之间,说明不需要考虑空值的情况
     */
    public boolean isSymmetric(TreeNode root) {
          
                TreeNode node1=root.left;
                TreeNode node2=root.right;
                return check(node1,node2);
         
           
    
    }
    public boolean check(TreeNode p, TreeNode q) {
        if (p == null && q == null) {
            return true;
        }
        if (p == null || q == null) {
            return false;
        }
        return p.val == q.val && check(p.left, q.right) && check(p.right, q.left);
    }
}

第十三天:

第一题,翻转二叉树

 

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        TreeNode left = invertTree(root.left);
        TreeNode right = invertTree(root.right);
        root.left = right;
        root.right = left;
        return root;



    }

}

第二题:路径总和

 

 分析:存在某一条路径之后等于目标值,就返回true,如果全部执行完成之后还没有得到true,会返回false。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    /**
    分析,首先需要知道,题目给我们的意思
    targetSum=一条路径里面的所有节点值的和
     */
    public boolean hasPathSum(TreeNode root, int targetSum) {
         if (root == null) {
            return false;
        }
        if (root.left == null && root.right == null) {
            return targetSum == root.val;
        }
        return hasPathSum(root.left, targetSum- root.val) || hasPathSum(root.right, targetSum - root.val);

  
    }
      
}

第三题,二叉树的搜索数中的搜索

 

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        while (root != null) {
            if (val == root.val) {
                return root;
            }
            root = val < root.val ? root.left : root.right;
        }
        return null;

                                                  
    }
    
}

第十四天

第一题,二叉树的插入操作

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        while (root != null) {
            if (val == root.val) {
                return root;
            }
            root = val < root.val ? root.left : root.right;
        }
        return null;

                                                  
    }
    
}

第二题,验证二叉搜索数,

分析:如果该二叉树中的一个节点中出现了一个root.left.val的值大于root.val的值,此时会返回false,如果没有出现这一情况,则会返回true,

代码段

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
  private TreeNode pre = null;
    public boolean isValidBST(TreeNode root) {
          return isValid(root);          
    }
    private boolean isValid(TreeNode root){
        if(root == null) return true; // 空节点,返回默认为true
        boolean left = isValid(root.left);
        if(pre!=null && pre.val>=root.val) return false; // 逆序,返回false
        pre = root; // 保存上一个节点
        boolean right = isValid(root.right);
        return left && right;
    }
}

第三题,两数之和,输入BST

分析:这道题可以采用HashSet的方法来进行这道题的解答

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean findTarget(TreeNode root, int k) {
        Set < Integer > set = new HashSet();
        return find(root, k, set);
    }
    public boolean find(TreeNode root, int k, Set < Integer > set) {
        if (root == null)
            return false;
        if (set.contains(k - root.val))
            return true;
        set.add(root.val);
        return find(root.left, k, set) || find(root.right, k, set);
    }
}

第四题,二叉数的最近的公共祖先

分析:看了一遍题目,去写,老是出现报错,最后执行总是出现那个错误,我去看了一下答案,答案它是先进行的递归,直到最后的值

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root== null || root == p || root == q)
            return root;
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if (left == null)
            return right;
        //同上
        if (right == null)
            return left;
        
        return root;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值