LeetCode记录

简单

590. N叉树的后序遍历

给定一个 N 叉树,返回其节点值的后序遍历。

例如,给定一个 3叉树 :
在这里插入图片描述
返回其后序遍历: [5,6,3,2,4,1].
说明: 递归法很简单,你可以使用迭代法完成此题吗?
在这里插入图片描述

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val,List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
    List<Integer> list=new ArrayList<Integer>();
    //迭代方法
    /*public List<Integer> postorder(Node root) {
        Stack<Node> stack=new Stack<>();
        if(root!=null){
            stack.add(root);
        }
        while(stack.size()>0){
            Node node=stack.pop();//出栈
            list.add(0,node.val);//头插法
            for(Node t:node.children){
                stack.add(t);
            }
        }
        return list;
    }*/
    //递归方法
    public List<Integer> postorder(Node root){
         postorder(root,list);
        return list;
    }
    public void postorder(Node node,List<Integer> list){
        if(node==null){
            return;
        }
        for(Node n:node.children){
            postorder(n,list);
        }
        list.add(node.val);
    }
}

589 N叉树的前序遍历

给定一个 N 叉树,返回其节点值的前序遍历。

例如,给定一个 3叉树 :
在这里插入图片描述
返回其前序遍历: [1,3,5,6,2,4]。

说明: 递归法很简单,你可以使用迭代法完成此题吗?
在这里插入图片描述

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val,List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
    List<Integer> list=new ArrayList<>();
    //借用栈辅助迭代
    /*public List<Integer> preorder(Node root) {
        Stack<Node> stack=new Stack<>();
        if(root!=null){
            stack.add(root);
        }
        while(stack.size()>0){
            Node node=stack.pop();
            list.add(node.val);
            for(int i=node.children.size()-1;i>=0;i--){
                stack.add(node.children.get(i));
            }
        }
        return list;
    }*/
    public List<Integer> preorder(Node root){
        //借用队列辅助迭代
        LinkedList<Node> queue=new LinkedList<>();
        if(root!=null){
            queue.addFirst(root);
        }
        while(queue.size()>0){
            Node node=queue.removeFirst();
            list.add(node.val);
            queue.addAll(0,node.children);
        }
        return list;
    }
    
}

递归方法

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val,List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
    //递归方法
    public List<Integer> preorder(Node root) {
        List<Integer> list=new ArrayList<>();
        bianLi(root,list);
        return list;
        
    }
    private void bianLi(Node root,List<Integer> list){
        if(root==null){
            return;
        }
        list.add(root.val);
        if(root.children!=null){
            for(Node node:root.children){
                bianLi(node,list);
            }
           
        }
        
    }
}

292. Nim游戏

你和你的朋友,两个人一起玩 Nim游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。

你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。

示例:

输入: 4
输出: false
解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛;
因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。
在这里插入图片描述

class Solution {
    public boolean canWinNim(int n) {
        return n%4!=0;
    }
}

617. 合并二叉树

给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

示例 1:

输入:
Tree 1 Tree 2
1 2
/ \ / \
3 2 1 3
/ \ \
5 4 7
输出:
合并后的树:
3
/
4 5
/ \ \
5 4 7
注意: 合并必须从两个树的根节点开始。
在这里插入图片描述

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
        if(t1==null&&t2==null){
            return null;
        }
        TreeNode n=new TreeNode(0);
        mergeTrees(n,t1,t2);
        return n;
    }
    private void mergeTrees(TreeNode node,TreeNode t1,TreeNode t2){
        if(t1==null&&t2==null){
            return ;
        }
        
        if(t1!=null&&t2!=null){ 
            node.val=t1.val+t2.val;
            if(t1.left!=null||t2.left!=null){
                node.left=new TreeNode(0);
                mergeTrees(node.left,t1.left,t2.left);
            }
            if(t1.right!=null||t2.right!=null){
                node.right=new TreeNode(0);
                mergeTrees(node.right,t1.right,t2.right);
            }
        }else if(t1!=null&&t2==null){
            node.val=t1.val;
            if(t1.left!=null){
                node.left=new TreeNode(0);
                mergeTrees(node.left,t1.left,null);
            }
            if(t1.right!=null){
                node.right=new TreeNode(0);
                mergeTrees(node.right,t1.right,null);
            }
        }else if(t1==null&&t2!=null){
            node.val=t2.val;
            if(t2.left!=null){
                node.left=new TreeNode(0);
                mergeTrees(node.left,null,t2.left);
            }
            if(t2.right!=null){
                node.right=new TreeNode(0);
                mergeTrees(node.right,null,t2.right);
            }
        }
        
        
    }
}

942. 增减字符串匹配

给定只含 “I”(增大)或 “D”(减小)的字符串 S ,令 N = S.length。

返回 [0, 1, …, N] 的任意排列 A 使得对于所有 i = 0, …, N-1,都有:

如果 S[i] == “I”,那么 A[i] < A[i+1]
如果 S[i] == “D”,那么 A[i] > A[i+1]

示例 1:

输出:“IDID”
输出:[0,4,1,3,2]
示例 2:

输出:“III”
输出:[0,1,2,3]
示例 3:

输出:“DDI”
输出:[3,2,0,1]
在这里插入图片描述

class Solution {
    public int[] diStringMatch(String S) {
        int i=0;
        int d=S.length();
        int[] arr=new int[S.length()+1];
        for(int k=0;k<S.length();k++){
            arr[k]=S.charAt(k)=='I'?i++:d--;
        }
        arr[S.length()]=i;
        return arr;
    }
}

删除链表倒数第n个节点

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
       
        
        if(head==null||head.next==null){
            return null;
        }
        ListNode left=head;
        ListNode right=head;
        for(int i=0;i<n;i++){
            right=right.next;
        }
        if(right==null){
            return head.next;
        }
        while(right.next!=null){
            right=right.next;
            left=left.next;
        }
        left.next=left.next.next;
        return head;
    }
}

206 反转链表

反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
在这里插入图片描述
递归法
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        //递归
        if(head==null||head.next==null){
            return head;
        }
        ListNode h=reverseList(head.next);
        head.next.next=head;
        head.next=null;
        return h;
       /* if(head==null||head.next==null){
            return head;
        }
        ListNode root=new ListNode(0);
        ListNode n=root;
        while(head!=null){
            n=head;
            head=head.next;
            n.next=root.next;
            root.next=n;
        }
        return root.next;*/
    }
}

203删除链表元素

删除链表中等于给定值 val 的所有节点。

示例:

输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
在这里插入图片描述

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

328奇偶链表

给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。

请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。

示例 1:

输入: 1->2->3->4->5->NULL
输出: 1->3->5->2->4->NULL
示例 2:

输入: 2->1->3->5->6->4->7->NULL
输出: 2->3->6->7->1->5->4->NULL
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode oddEvenList(ListNode head) {
        if(head==null){
            return head;
        }
        ListNode ji=head;
        ListNode ou=head.next;
        ListNode ouStart=head.next;
        while(ou!=null&&ou.next!=null){
            ji.next=ji.next.next;
            ou.next=ou.next.next;
            ou=ou.next;
            ji=ji.next;
        }
        ji.next=ouStart;
        return head;
    }
}

234回文链表

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false
示例 2:

输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head==null||head.next==null){
            return true;
        }
        ListNode mid=findMid(head);
        ListNode h=head;
        ListNode p=reverse(mid.next);
        while(p!=null&&h.val==p.val){
            p=p.next;
            h=h.next;
        }
        return p==null;
    }
    private ListNode findMid(ListNode head){
       if(head==null){
           return null;
       }
        ListNode slow=head;
        ListNode fast=head.next;
        while(fast!=null&&fast.next!=null){
            slow=slow.next;
            fast=fast.next.next;
        }
        return slow; 
    }
    private ListNode reverse(ListNode head){
        if(head==null||head.next==null){
            return head;
        }
        ListNode h=reverse(head.next);
        head.next.next=head;
        head.next=null;
        return h;
    }
}

21合并两个有序链表

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode h1=l1;
        ListNode h2=l2;
        ListNode h=new ListNode(0);
        ListNode cur=h;
        while(h1!=null&&h2!=null){
           if(h1.val<=h2.val){
                cur.next=h1;
                h1=h1.next;
               
            }else{
                cur.next=h2;
                h2=h2.next;
            }
            cur=cur.next;
            cur.next=null;
        }
        if(h1!=null){ 
            cur.next=h1;
            
        }
        if(h2!=null){
            cur.next=h2;
            
        }
        return h.next;
    }
}

2两数相加

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode h=new ListNode(0);
        ListNode p=h;
        int carry=0;
        while(l1!=null||l2!=null||carry==1){
           int num=((l1==null)?0:l1.val)+((l2==null)?0:l2.val)+carry;
            ListNode n=new ListNode(num%10);
            p.next=n;
            p=p.next;
            carry=num/10;
            l1=(l1==null)?null:l1.next;
            l2=(l2==null)?null:l2.next;
        }
        return h.next;
    }
}

724寻找数组的中心索引

给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法。

我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和。

如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。

示例 1:

输入:
nums = [1, 7, 3, 6, 5, 6]
输出: 3
解释:
索引3 (nums[3] = 6) 的左侧数之和(1 + 7 + 3 = 11),与右侧数之和(5 + 6 = 11)相等。
同时, 3 也是第一个符合要求的中心索引。

class Solution {
    public int pivotIndex(int[] nums) {
        int len=nums.length;
        if(len==1){
            return 0;
        }
        int sum=0;
        int left=0;
        int right=0;
        for(Integer num:nums){
            sum+=num;
        }
        for(int i=0;i<len;i++){
           if(i==0){
               left=0;
           }else{
               left+=nums[i-1];
           }
            right=sum-left-nums[i];
            if(left==right){
                return i;
            }
        }
        return -1;
    }
}

66 加一

给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。

最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

示例 1:

输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
示例 2:

输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。
在这里插入图片描述

class Solution {
    public int[] plusOne(int[] digits) {
        int carry=0;
        for(int i=digits.length-1;i>=0;i--){
            if(carry==1||(i==digits.length-1)){
                int num=digits[i]+1;
                carry=num/10;
                num=num%10;
                digits[i]=num;
            }
        }
        if(carry==1){
                int[] newArr=new int[digits.length+1];
                for(int j=0;j<digits.length;j++){
                    newArr[j+1]=digits[j];
                }
                digits=newArr;
                digits[0]=1;
        }
        return digits;
    }
}

169 求众数

给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在众数。

示例 1:

输入: [3,2,3]
输出: 3
示例 2:

输入: [2,2,1,1,1,2,2]
输出: 2
在这里插入图片描述

class Solution {
    public int majorityElement(int[] nums) {
        int max=nums[0];
        int count=1;
        for(int i=0;i<nums.length;i++){
            if(max==nums[i]){
                count++;
            }else{
                count--;
                if(count==0){
                    max=nums[i];
                    count=1;
                }
            }
        }
        return max;
    }
}

中等

240搜索二维矩阵

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:

每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
示例:

现有矩阵 matrix 如下:

[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。

给定 target = 20,返回 false。
在这里插入图片描述

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int i=matrix.length-1;
        int j=0;
        if(matrix==null||matrix.length<1||matrix[0].length<1){
            return false;
        }
        while(true){
           if(target==matrix[i][j]){
               return true;
           }else if(target<matrix[i][j]){
               i--;
           }else if(target>matrix[i][j]){
               j++;
           }
            if(i<0||j==matrix[0].length){
                break;
            }
        }
        return false;
    }
}

54螺旋矩阵

给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

示例 1:

输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:

输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
在这里插入图片描述
自己的做法

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> list=new ArrayList<Integer>();
        if(matrix==null||matrix.length<1){
            return list;
        }
        int left=0;
        int right=matrix[0].length-1;
        int up=0;
        int down=matrix.length-1;
        int count=0;
        while(left!=right||up!=down){
            //向右
            if(up!=down){
                for(int i=left;i<=right;i++){
                    list.add(matrix[up][i]);
                    count++;
                }
                up++;
            }else{
                for(int i=left;i<=right;i++){
                    list.add(matrix[up][i]);
                    count++;
                }
                break;
            }
            //向下
            if(left!=right){
                for(int i=up;i<=down;i++){
                    list.add(matrix[i][right]);
                    count++;
                }
                right--;
            }else{
                 for(int i=up;i<=down;i++){
                    list.add(matrix[i][right]);
                     count++;
                }
                break;
            }
            //向左
            if(up!=down){
                for(int i=right;i>=left;i--){
                    list.add(matrix[down][i]);
                    count++;
                }
                down--;
            }else{
                for(int i=right;i>=left;i--){
                    list.add(matrix[down][i]);
                    count++;
                }
                break;
            }
            //向上
            if(left!=right){
                for(int i=down;i>=up;i--){
                    list.add(matrix[i][left]);
                    count++;
                }
                left++;
            }else{
                for(int i=down;i>=up;i--){
                    list.add(matrix[i][left]);
                    count++;
                }
                break;
            }
           
        }
        if(count!=matrix.length*matrix[0].length){
            list.add(matrix[up][left]);
        }
        return list;
    }
}

用一个二维状态数组做辅助

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> list=new ArrayList<Integer>();
        if(matrix==null||matrix.length==0){
            return list;
        }
        int row=matrix.length;
        int col=matrix[0].length;
        int count=row*col;
        boolean[][] flag=new boolean[row][col];//状态数组
        int x=0;
        int y=0;
        while(true){
            if(count==list.size()){
                break;
            }
            //向右
            while(x<col&&!flag[y][x]){
                list.add(matrix[y][x]);
                flag[y][x]=true;
                x++;
            }
            x--;
            y++;
            //向下
            while(y<row&&!flag[y][x]){
                list.add(matrix[y][x]);
                flag[y][x]=true;
                y++;
            }
            y--;
            x--;
            //向左
            while(x>=0&&!flag[y][x]){
                list.add(matrix[y][x]);
                flag[y][x]=true;
                x--;
            }
            x++;
            y--;
            //向上
            while(y>=0&&!flag[y][x]){
                list.add(matrix[y][x]);
                flag[y][x]=true;
                y--;
            }
            y++;
            x++;
        }
        return list;
    }
}

173. 二叉搜索树迭代器

实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。

调用 next() 将返回二叉搜索树中的下一个最小的数。
在这里插入图片描述
在这里插入图片描述

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class BSTIterator {
    Stack<TreeNode> stack=new Stack<>();
    public BSTIterator(TreeNode root) {
        TreeNode cur=root;
        while(cur!=null){
            stack.push(cur);
            cur=cur.left;
        }
    }
    
    /** @return the next smallest number */
    public int next() {
        TreeNode n=stack.pop();
        TreeNode cur=n.right;
        while(cur!=null){
            stack.push(cur);
            cur=cur.left;
        }
        return n.val;
    }
    
    /** @return whether we have a next smallest number */
    public boolean hasNext() {
        return stack.size()!=0;
    }
}

/**
 * Your BSTIterator object will be instantiated and called as such:
 * BSTIterator obj = new BSTIterator(root);
 * int param_1 = obj.next();
 * boolean param_2 = obj.hasNext();
 */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值