刷题
一、链表
public class ListNode{
int val;
ListNode next;
ListNode (int x){
val = x;
next = null;
}
}
1.相交链表
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode l1 = headA;
ListNode l2 = headB;
while(l1 != l2){
l1 = (l1 == null)?headB:l1.next;
l2 = (l2 == null)?headA:l2.next;
}
return l1;
}
}
2.链表翻转(单向链表)
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null){
return head;
}
ListNode pre = null;
while(head != null){
ListNode cur = head;
head = head.next;
cur.next = pre;
pre = cur ;
}
return pre;
}
}
3.归并两个 有序 链表
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
while(l1 != null && l2 != null){
if(l1.val < l2.val){
cur.next = l1;
cur = cur.next;
l1= l1.next;
}else{
cur.next = l2;
cur = cur.next;
l2 = l2.next;
}
}
while(l1 != null){
cur.next = l1;
cur = cur.next;
l1 = l1.next;
}
while(l2 != null){
cur.next = l2;
cur = cur.next;
l2 = l2.next;
}
return dummy.next;
}
}
4.从有序链表删除重复的
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if(head ==null) return head;
ListNode cur = head;
while(cur !=null && cur.next != null){
if(cur.val == cur.next.val){
cur.next = cur.next.next;
}else{
cur = cur.next;
}
}
return head;
}
}
5.回文链表
class Solution {
public boolean isPalindrome(ListNode head) {
ArrayList<Integer> list = new ArrayList<>();
if(head == null) return true;
while(head!= null){
list.add(head.val);
head=head.next;
}
int left = 0;
int right = list.size()-1;
while(left<right){
if(!list.get(left).equals(list.get(right))){
return false;
}
left++;
right--;
}
return true;
}
}
5.链表中倒数第K个结点
class Solution{
public ListNode getKthFromEnd(ListNode head,int k){
ListNode fast = head;
ListNode slow = head;
//slow和fast之间的距离就是k
for(int i=0;i<k;i++){
fast = fast.next;
}
while(fast != null){
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
二、树
1.树的高度
class Solution {
public int maxDepth(TreeNode root) {
if(root == null) return 0;
return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
}
}
2.平衡树
class Solution {
public boolean isBalanced(TreeNode root) {
if(root == null) return true;
return isBalanced(root.left) && isBalanced(root.right) && Math.abs(depth(root.left) - depth(root.right))<2;
}
//计算树的高度
public int depth(TreeNode root){
if(root == null) return 0;
return Math.max(depth(root.left),depth(root.right))+1;
}
}
3.二叉树的直径
遍历左边的高度加上右边的高度
class Solution {
int max=0;
public int diameterOfBinaryTree(TreeNode root) {
if(root == null) return 0;
recur(root);
return max;
}
//计算高度
public int recur(TreeNode root){
if(root == null) return 0;
int leftMax = recur(root.left);
int rightMax = recur(root.right);
max = Math.max(leftMax+rightMax,max);
return Math.max(leftMax,rightMax)+1;
}
}
4.翻转二叉树(用bfs非递归的方式(LinkedList))
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
TreeNode treenode = queue.poll();
if(treenode.left != null){
queue.add(treenode.left);
}
if(treenode.right != null){
queue.add(treenode.right);
}
//交换
TreeNode tmp = treenode.left;
treenode.left = treenode.right;
treenode.right = tmp;
}
return root;
}
}
5.二叉树每层的平均值
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
ArrayList<Double> res=new ArrayList<>();//用来存结果的平均值的数组
LinkedList<TreeNode> queue = new LinkedList<>();//用来存数据
if(root == null) return res;
queue.add(root);
while(!queue.isEmpty()){
double sum=0;//要注意,求均值一定要用double,或者类型大的,不然会产生溢出
int count=queue.size();
//使用一个队列解决问题,关键点在于使用queue.size(),先提前知道上一层的个数并记录
for(int i=0;i<count;i++){
TreeNode n=queue.poll();
sum +=n.val;
//将取出来的结点的左孩子和右孩子,放到queue中去。
//遍历只遍历到count长度的位置
if(n.left != null) queue.add(n.left);
if(n.right != null) queue.add(n.right);
}
res.add(sum/count);
}
return res;
}
}
6.左子节点的和
class Solution {
int count=0;
public int sumOfLeftLeaves(TreeNode root) {
if(root == null) return 0;
//两点:左节点 、 叶子结点
if(root.left != null &&(root.left.left == null && root.left.right == null)){
count = count +root.left.val;
}
sumOfLeftLeaves(root.left);
sumOfLeftLeaves(root.right);
return count;
}
}
7.对称二叉树(检查一个树是不是镜像对称的)
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
return isSymmetricTree(root.left,root.right);
}
public boolean isSymmetricTree(TreeNode s,TreeNode t){
if(s == null && t == null) return true;//都是叶子结点
if(s==null ||t==null) return false;//其中一个是叶子节点
if(s.val != t.val) return false;//值不相等
return isSymmetricTree(s.left,t.right) && isSymmetricTree(s.right,t.left);
}
}
8.前序遍历的非递归实现
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ret = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
if (node == null) continue;
ret.add(node.val);
stack.push(node.right); // 先右后左,保证左子树先遍历
stack.push(node.left);
}
return ret;
}
9.二叉搜索树的最近公共祖先
class Solution {
//二叉搜索树的最近公共祖先
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return null;
if(p.val > root.val && q.val >root.val){
return lowestCommonAncestor(root.right,p,q);
}
if(p.val <root.val && q.val<root.val){
return lowestCommonAncestor(root.left,p,q);
}
return root;
}
}
10.二叉树的最近公共祖先
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return null;
if(root.val == p.val || root.val == q.val) return root;
//先判断当前点,然后在去找要找的p和q在左边还是右边
TreeNode left=lowestCommonAncestor(root.left,p,q);
TreeNode right=lowestCommonAncestor(root.right,p,q);
//如果左边没有,肯定是在右边
if(left == null){
return right;
}
//如果右边没有,肯定是在左边
if(right == null){
return left;
}
if(left != null && right != null) return root;
return null;
}
}