LeetCode之两数相加反转链表少箭射球二叉树

Posted 刘兆贤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode之两数相加反转链表少箭射球二叉树相关的知识,希望对你有一定的参考价值。

     本文来自刘兆贤的博客_CSDN博客-Java高级,Android旅行,Android基础领域博主 ,引用必须注明出处!

 以前也有刷一些题目,但是没有记录,不方便回头看解题思路,今天开始就记录一下。

力扣刷了300题,地址:iddo - 力扣(LeetCode)

力扣

两个链表,分别纪录从个数开始的数,相加后得到新的链表

思路:递归。保留当前结点,提高连结效率。

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) 
        return getResult(l1,l2,null,null,0);
    

    public ListNode getResult(ListNode l1,ListNode l2,ListNode target,ListNode next,int addHigh)
        if(l1==null&&l2==null&&addHigh==0)
            return target;
        
        int lv=0;
        int rv=0;
        if(l1!=null)
            lv=l1.val;
            l1=l1.next;
        
        if(l2!=null)
            rv=l2.val;
            l2=l2.next;
        
        int total=lv+rv+addHigh;
        int newVal=total;
        int newHigh=0;
        if(total>9)
            if(total==10)
                newVal=0;
            else
                newVal=total%10;
            
            newHigh=1;
        
        ListNode temp=new ListNode(newVal);
        if(target==null)
            target=temp;
        else
            if(next!=null)
                next.next=temp;
                next=next.next;
            else
                target.next=temp;
                next=target.next;
            
        
        return getResult(l1,l2,target,next,newHigh);
    

执行速度还是蛮快的,内存也还好。

https://leetcode-cn.com/problems/reverse-linked-list/

反转链表

解法一:分别获得各结点,然后重新组成新的链表。重组过程:每次移动指针,将结点绑定。以此为核心思路,演化出第二种解法。

	private static ListNode reverseListNode(ListNode head) 
		List<ListNode> list = getListNodeSize(head, new ArrayList<>());
		ListNode preNode = null;
		for (int i = list.size() - 1; i > -1; i--) 
			ListNode node = list.get(i);
			// 切断结点
			node.next = null;
			if (preNode == null) 
				// 赋值初结点
				preNode = node;
			 else 
				// 临时结点
				ListNode temp = preNode.next;
				if (temp != null) 
					while (temp.next != null) 
						// 每次都将指针移到最后一个,查到最后一个结点
						temp = temp.next;
					
					temp.next = node;
				 else 
					preNode.next = node;
				
			
		
		return preNode;
	

	private static List<ListNode> getListNodeSize(ListNode head, List<ListNode> list) 
		while (head != null) 
			list.add(head);
			return getListNodeSize(head.next, list);
		
		return list;
	

解法二:关键在于,使用指针结点,对新的链表进行递归赋值;演化出第三种方法。

	private static ListNode reverseListNode(ListNode head) 
		return reverseNode(head, null);
	

	/**
	 * 
	 * @param curNode
	 *            指针结点
	 * @param headNode
	 *            新的链表
	 * @return
	 */
	private static ListNode reverseNode(ListNode curNode, ListNode headNode) 
		// 指针结点为空
		if (curNode == null) 
			return headNode;
		
		// 新的链表
		if (headNode == null) 
			headNode = new ListNode(curNode.val);
		
		// 指针结点
		ListNode nextNode = curNode.next;
		if (nextNode == null) 
			return headNode;
		
		// 新链表结点
		curNode = new ListNode(nextNode.val);
		curNode.next = headNode;
		return reverseNode(nextNode, curNode);
	

解法三:利用head结点作为基础,不断使用后续结点,充当head的父结点。

	/**
	 * 内循环算法
	 * 
	 * @param head
	 * @return
	 */
	public static ListNode reverseInnerLoop(ListNode head) 
		ListNode newNode = null;
		while (head != null) 
			// 下个结点
			ListNode nextNode = head.next;
			// 将head的下一个,指向新结点
			head.next = newNode;
			// 得到新的结点,完成反指
			newNode = head;
			// 指针结点,实现循环
			head = nextNode;
		
		return newNode;
	

力扣

求完全二叉树(除底层,其他层次都满)的结点个数。

思路:笨办法,递归获得

    public int countNodes(TreeNode root) 
		int count = 0;
		if (root == null) 
			return count;
		
		count++;
		int index = 0;
		if (root.left != null) 
			count += countNodes(root.left);
		
		if (root.right != null) 
			count += countNodes(root.right);
		
		return count;
    

新算法:

  public int countNodes(TreeNode root) 
		int count = 0;
		if (root == null) 
			return count;
		
        int ld=depth(root.left);
        int rd=depth(root.right);
        //根结点
        if(ld==rd)
            int lc=1<<ld;
            System.out.println("lc:"+lc);
            return lc+countNodes(root.right);
        
        int rc=1<<rd;
        System.out.println("rc:"+rc);
        return rc+countNodes(root.left);
    

    public int depth(TreeNode node)
        int count=0;
        while(node!=null)
            count++;
            node=node.left;
        
        return count;
    

虽然使用了完全二叉树的原理,但是由于不断移位产生新的对象,耗时和内存都增加了。

力扣

贪心算法:求局部最优解。

二维空间中,x到y,给定气球坐标,全部射中需要的最少箭数。

思路:先排序,以数列首个数字从小到大排列,使用低位和高位循环匹配,不符合的需要再用一支箭头即结果+1,于是解出此题。

	public static int findMinArrowShots(int[][] points) 
		if (points.length == 0) 
			return 0;
		
		// 从大到小排序
		Arrays.sort(points, new Comparator<int[]>() 

			@Override
			public int compare(int[] o1, int[] o2) 
				return o1[0] - o2[0];
			
		);
		// 检查
		int low = points[0][0];
		int high = points[0][1];
		int result = 1;
		for (int aIndex = 1; aIndex < points.length; aIndex++) 
			int[] bttr = points[aIndex];
			if (bttr[0] >= low && bttr[0] <= high) 
				// 默认第1个数据,就是低位和高位,后面逐步缩小范围,最后囊括所有数据
				if (bttr[0] > low) 
					low = bttr[0];
				
				if (bttr[1] < high) 
					high = bttr[1];
				
				continue;
			 else 
				// 不符合,则使用新箭
				low = points[aIndex][0];
				high = points[aIndex][1];
			
			result++;
		
		return result;
	

力扣

又是贪心算法,求穿墙最少,需要几条垂线

    public int leastBricks(List<List<Integer>> wall) 
        //注意,使用按key排序的map集合,将所有的值,和出现的次数保存起来
        Map<Integer,Integer> map=new TreeMap();
        //找出值最大的key
        int maxKey=0;
        for(List<Integer> sec:wall)
            int key=0;
            for(Integer value:sec)
                key+=value;
                Integer num=map.get(key);
                if(key>maxKey)
                    maxKey=key;
                
                if(num==null)
                    map.put(key,1);
                else
                    map.put(key,num+1);
                
            
        
        int nums=0;
        int mostValue=0;
        Iterator<Integer> iterator=map.keySet().iterator();
        while(iterator.hasNext())
            Integer key=iterator.next();
            Integer val=map.get(key);
            if(val>=nums&&key<maxKey)
                //找到数量最多的,同时小于最大key,以防穿墙
                nums=val;
                //它的索引
                mostValue=key;
            
        
        System.out.print(mostValue);
        int count=0;
        for(List<Integer> sec:wall)
            int total=0;
            boolean exist=false;
            for(Integer se:sec)
                total+=se;
                if(total==mostValue)
                    //说明穿过缝隙
                    exist=true;
                    continue;
                else if(total>mostValue)
                    //说明已经超过缝隙
                    continue;
                
            
            if(!exist)
                count++;
            
        
        return count;
    

算法不够高明,但思路还算清晰。

二叉树,根据中序和后序,求原树。

中序:左根右

后序:左右根

前序:根左右
 

/**
 * 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 buildTree(int[] inorder, int[] postorder) 
        //后序的最后一个肯定是根结点,根据此定律,做递归
        if(inorder.length==0)
            return null;
        
        int iLen=inorder.length,pLen=postorder.length,val=postorder[pLen-1];
        TreeNode root=new TreeNode(val);
        for(int i=0;i<iLen;i++)
            if(inorder[i]==val)
                int[] in_left=Arrays.copyOfRange(inorder,0,i);
                int[] in_right=Arrays.copyOfRange(inorder,i+1,iLen);
                int[] post_left=Arrays.copyOfRange(postorder,0,i);
                int[] post_right=Arrays.copyOfRange(postorder,i,pLen-1);
                root.left=buildTree(in_left,post_left);
                root.right=buildTree(in_right,post_right);
                break;
            
        
        return root;
    

遍历:所有数据都访问到,且只访问一次。

求质数小技巧:最大质数小于等于值的平方根。

TreeMap,key自动排序的Map;TreeSet,值自动排序的List。

以上是关于LeetCode之两数相加反转链表少箭射球二叉树的主要内容,如果未能解决你的问题,请参考以下文章

力扣之两数相加

ACM之两数相加问题

leetcode之两数相加解题思路

leetcode之两数相加解题思路

LeetCode Hot 100 --- 两数相加(java)

字节跳动高频算法题TOP100