剑指Offer系列(3~10题,JAVA版)

题顺序按照剑指Offer,实际运行在牛客网。讲解见《剑指Offer》

代码实现

  1. 剑指Offer思路
public class Solution {
	public boolean duplicate(int numbers[],int length,int [] duplication) {
		int res = -1;
		for(int i=0;i<length;i++) {
			int temp = numbers[i];
			int index = i;
			while(numbers[index]!=index) {
				//  把当前值/所对应的下表标/所对应的元素 /与当前值交换位置
				if(numbers[index]==numbers[numbers[index]]) { //如果当前值与 以当前值作为下标的值相同,则找到重复
					res = numbers[index];
					duplication[0] = res;
					return res != -1;
				}
				temp = numbers[index];
				numbers[index] = numbers[temp];
				numbers[temp]=temp;
			}
		}
		return res != -1;
	}
}
  1. 使用Map(个人理解)
public class Solution {
    public boolean duplicate(int numbers[],int length,int [] duplication) {
    	if(length==0) {
    		return false;
    	}else {
	    	TreeMap<Integer,Integer> map = new TreeMap<>();
	    	for(int num:numbers) {
	    		if(map.get(num)!=null) {
	    			map.put(num, map.get(num)+1);
	    		}else {
	    			map.put(num, 1);
	    		}
	    	}
	    	Random rand = new Random();
	    	ArrayList<Integer> list = new ArrayList<>();
	    	for(int key:map.keySet()) {
	    		if(map.get(key)>1) {
	    			list.add(key);
	    		}
	    	}
	    	if(list.size()!=0) {
		    	int randIndex = rand.nextInt(list.size());
		    	duplication[0] = list.get(randIndex);
		    	return true;
	    	}else {
	    		return false;
	    	}
    	}
    }

代码实现

  1. 剑指Offer思路
public class Solution {   
    public boolean Find(int target, int [][] array) {
    	if(array==null || array[0].length==0 ) {
    		return false;
    	}
    	int com = 0;
    	int row = array.length-1;

    	while(com<array.length && row>=0) {
    		if(target == array[com][row]) {
    			return true;
    		}
	    	if(target<array[com][row]) {	//删除列
	    		row --;
	    	}else if(target>array[com][row]) {	//删除行
		    	com ++;
	    	}
    	}
    	return false;
    }
}
  1. 按照每一行(列)采用二分查找(个人理解)
public class Solution {   
public boolean Find(int target, int [][] array) {
    	int size = array.length;
    	boolean flag;
    	for(int i=0;i<size;i++) {
    		flag = binarySearch(array[i],target);
    		if(flag==true) {
    			return true;
    		}
    	}
    	return false;
    }
    public boolean binarySearch(int[] arr,int target) {
    	int min = 0;
    	int max = arr.length-1;
    	while(max>=min) {
    		int mid = (min+max)/2;
    		if(arr[mid]<target) {
    			min = mid+1;
    		}else if(arr[mid]>target) {
    			max = mid -1;
    		}else {
    			return true;
    		}
    	}
    	return false;
    }
}

代码实现

  1. 剑指Offer思路
public class Solution {   
public String replaceSpace(StringBuffer str) {
    	int count=0;
    	for(int i=0;i<str.length();i++) {
    		if(str.charAt(i)==' ') {
    			count++;
    		}
    	}
    	char[] newChar = new char[str.length()+2*count];
    	for(int i=str.length()-1,j=newChar.length-1;i>=0 && j>=0;i--,j--) {
    		if(str.charAt(i)!=' ') {
    			newChar[j] = str.charAt(i); 
    		}else {
    			newChar[j--]='0';
    			newChar[j--]='2';
    			newChar[j]='%';
    		}
    	}
    	String L="";
    	for(int i=0;i<newChar.length;i++) {
    		L = L+newChar[i];
    	}
    	return L;
    }
}
  1. 使用StringBuilder
public class Solution {  
public String replaceSpace(StringBuffer str) {
    	StringBuilder res = new StringBuilder();
    	for(int i=0;i<str.length();i++) {
    		char cha = str.charAt(i);
    		if(cha != ' ') {
    			res.append(cha);
    		}else {
    			res.append("%20");
    		}
    	}
    	return res.toString();
    }
}

代码实现

  1. 利用栈
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
	public static class ListNode{
		int val;
		ListNode next = null;
		public ListNode(int val) {
			this.val = val;
		}
	}
	
    public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> list = new ArrayList<>();
        Stack<Integer> stack = new Stack<Integer>();
        while(listNode!=null) {
        	stack.add(listNode.val);
        	listNode = listNode.next;
        }
        while(!stack.isEmpty()) {
        	list.add(stack.pop());
        }
        return list;
    }
    //测试用例
    public static void main(String[] args) {
		ListNode node = new ListNode(0);
		ListNode tnode = node;
    	for(int i=1;i<10;i++) {
			node.next = new ListNode(i);
			node = node.next;
		}
    	ArrayList<Integer> list = printListFromTailToHead(tnode);
    	System.out.println(list);
	}
}
  1. 利用递归实现
import java.util.ArrayList;
public class Solution {
	public static class ListNode{
		int val;
		ListNode next = null;
		public ListNode(int val) {
			this.val = val;
		}
	}
	
    public static ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        if(listNode==null) {
        	return new ArrayList<Integer>();
        }
    	ArrayList<Integer> list = new ArrayList<>();
        ListNode root = reverseNode(listNode);
        while(root!=null) {
        	list.add(root.val);
        	root = root.next;
        }
        return list;
    }
    public static ListNode reverseNode(ListNode listNode) {
    	ListNode root = new ListNode(listNode.val);
    	root = reverseNode(root,listNode.next);
    	return root;
    }
    
    private static ListNode reverseNode(ListNode root,ListNode listNode) {
    	if(listNode==null) {
    		return root;
    	} 
    	ListNode rightNode = listNode.next;
    	listNode.next = root;
    	root = listNode;
    	return reverseNode(root,rightNode);
    }
    
    //测试用例
    public static void main(String[] args) {
		ListNode node = new ListNode(0);
		ListNode tnode = node;
    	for(int i=1;i<10;i++) {
			node.next = new ListNode(i);
			node = node.next;
		}
    	ArrayList<Integer> list = printListFromTailToHead(tnode);
    	System.out.println(list);
	}
}
public class Solution {
	public class TreeNode {
		int val;
		TreeNode left;
		TreeNode right;
		public TreeNode(int x) {
			val = x;
		}
	}
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
        return root;
    }
    //前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
    private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,int [] in,int startIn,int endIn) {
         
        if(startPre>endPre||startIn>endIn)
            return null;
        TreeNode root=new TreeNode(pre[startPre]);//构建当前根节点
         
        for(int i=startIn;i<=endIn;i++)
            if(in[i]==pre[startPre]){
            	// (i-startIn)表示当满足in[i]==pre[startPre]条件时,数据发生偏移的位数
                root.left=reConstructBinaryTree(pre,startPre+1,startPre+(i-startIn),in,startIn,i-1);
                root.right=reConstructBinaryTree(pre,(i-startIn)+startPre+1,endPre,in,i+1,endIn);
            }
                 
        return root;
    }
}

思路分析:
在这里插入图片描述
代码实现:

/*
public class TreeLinkNode {
    int val;
    TreeLinkNode left = null;
    TreeLinkNode right = null;
    TreeLinkNode next = null;

    TreeLinkNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
        public TreeLinkNode GetNext(TreeLinkNode pNode)
    {	
    	TreeLinkNode resNode;
    	if (pNode == null)
            return pNode;
        if(pNode.right!=null) {
        	resNode = findMin(pNode.right);
        	return resNode;
        }
        if(pNode.right==null) {
        	if(pNode.next!=null && pNode.next.left == pNode) {
        		resNode = pNode.next;
        		return resNode;
        	}
        	if(pNode.next!=null && pNode.next.right == pNode) {
        		while(pNode.next!=null && pNode.next.left!=pNode) {
        			pNode = pNode.next;
        		}
        		return pNode.next;
        	}
        }
        return null;
    }
    public TreeLinkNode findMin(TreeLinkNode node) {
    	while(node.left!=null) {
    		node = node.left;
    	}
    	return node;
    }
}
  • 思考:如果要找到前序遍历的下一个节点呢?后序遍历的下一个节点呢?
    同理:对于前序遍历,分情况为
  1. 若当前节点存在左子树 ---- > 下一个节点就是这个左子树
  2. 若当前节点为父亲节点的左孩子且自身不存在左子树:
    Ⅰ.若父亲节点存在右子树 -----> 下一个节点就是父亲节点的右子树
    Ⅱ.若父亲节点不存在右子树 -----> 向上进行回溯,如果找到一个节点存在右节点,则:下一个节点就是这个节点的右节点
    Ⅲ.若父亲节点不存在右子树 ------> 向上回溯,一直回溯到根节点也没找到存在右节点的节点,则当前节点没有下一个节点
  3. 若当前节点为父亲节点的右孩子且自身不存在左子树:
    Ⅰ.向上一直回溯到根节点 -------> 若根节点存在右孩子,则下一个节点为根节点的右孩子
    Ⅱ.向上一直回溯到根节点 -------> 若根节点不存在右孩子,则下一个节点不存在

后序遍历同理:

  1. 若当前节点为其父节点的左孩子且父节点存在右子树 ---- > 下一个节点就是这个右子树中最靠左的元素
  2. 若当前节点为其父节点的右孩子 ---- >下一个节点就是其父节点

代码实现

  1. 剑指Offer
import java.util.Stack;
/*
 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
 */
public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
    	stack1.add(node);
    }
    
    public int pop() {
    	if(stack2.isEmpty()) {
	    	while(!stack1.isEmpty()) {
	    		stack2.push(stack1.pop());
	    	}
	    	return stack2.pop();
    	}else {
    		return stack2.pop();
    	}
    }
}
  1. 个人思路
import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
    	stack1.add(node);
    }
    public int pop() {
    	while(!stack1.isEmpty()) {
    		stack2.push(stack1.pop());
    	}
    	int res = stack2.pop();
    	while(!stack2.isEmpty()) {
    		stack1.push(stack2.pop());
    	}
    	return res;
    }
}
  • 第十题
    题目:斐波那契数列注意:不能使用递归!------- > 过多的重复无效运算!),利用循环求解:
    在这里插入图片描述
    代码实现
public class Solution {
    public int Fibonacci(int n) {
    	if(n==0 || n==1) {
    		return n;
    	}
    	int fibOne=1;
    	int fibTwo=0;
    	int fibN=0;
    	for(int i=2;i<=n;i++) {
    		fibN = fibOne + fibTwo;
    		fibTwo = fibOne;
    		fibOne = fibN;
    	}
    	return fibN;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值