()(1)二维数组中的查找
(2)重建二叉树
利用Arrays.copyOfRange(n,from,to)进行数组截取,实现起来更简便。
public TreeNode reConstructBinaryTree(int [] pre,int [] vin) {
int pren = pre.length;
int vinn = vin.length;
if(pren==0 || vinn==0)
return null;
int node = pre[0];
TreeNode root = new TreeNode(node);
for(int i = 0;i
(3)二叉树的下一个结点
(4)矩阵中的路径
更简便的代码:
1、将矩阵路径经过时改为‘.’,使用完再回复为原值。来代替flag矩阵记1
2、关于i,j是否超届的判断均放到最开始的if中用,超届则直接false;
3、易错点,到index最后一位匹配上就直接给true
public boolean hasPath (char[][] matrix, String word) {
for(int i=0;i=m.length||j<0||j>=m[0].length||m[i][j]!=word.charAt(index))
return false;
if(index==word.length()-1)
return true;
char t = m[i][j];
m[i][j] = '.';
boolean res = deepPath(m,i-1,j,word,index+1)||
deepPath(m,i+1,j,word,index+1)||
deepPath(m,i,j-1,word,index+1)||
deepPath(m,i,j+1,word,index+1);
m[i][j]=t;
return res;
}
(5)剪绳子
动态规划的思想是一定要从最小子问题开始求解,之后更大的问题可以应用其子问题的结果。
若该子问题出现多次,只需计算一次。
1、本题n=2和n=3与裁成了2和3的值不同。
因为n=2和n=3必须进行裁剪故对应1,2。但裁的段中有2和3时不需要继续裁最大为2,3.
其他的可以依次便利或得(不必排除裁成长度为1的段,因为肯定不如其他的值大)
public int cutRope (int n) {
// write code here
if(n==2)
return 1;
if(n==3)
return 2;
int[] max = new int[n+1];
max[1] = 1;
max[2] = 2;
max[3] = 3;
for(int i = 4;i<=n;i++){
for(int j=1;j
(6) 数值的整数次方
注意指数为负数时
(7)调整数组顺序使奇数位于偶数前面(一)
注意此题是调整后保持奇偶数内部的相对位置
(8)链表中环的入口结点
这里忽视的问题是,slow走一步,fast走两步是slow=pHead.next,fast=pHead.next.next;
错误1:slow=pHead,fast=pHead.next.next;这相当于slow一步没走
错误2:在一起走c步时,从pHead开始
(9)树的子结构
重点看一下递归部分。易忽略,如果一开始root1==null则肯定是false
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root1==null||root2==null)
return false;
Stack stack1 = new Stack();
stack1.push(root1);
while(!stack1.isEmpty()){
TreeNode node = stack1.pop();
if(isSame(node,root2)){
return true;
}
if(node.left!=null)
stack1.push(node.left);
if(node.right!=null)
stack1.push(node.right);
}
return false;
}
public boolean isSame(TreeNode node,TreeNode root2){
if(node==null&&root2!=null)
return false;
if(root2==null)
return true;
if(node.val!=root2.val)
return false;
return isSame(node.left,root2.left)&&isSame(node.right,root2.right);
}
(10)栈的压入、d出序列
空间复杂度小的方式:与用栈辅助思想一致,但时利用数组已经入栈的部分当作栈。
top指向栈顶,pushIndex指向下一个要 *** 作的数
public boolean IsPopOrder(int [] pushA,int [] popA) {
if(pushA.length==0)
return true;
int pushIndex = 0,top=-1,popIndex=0;
while(popIndex=0&&popA[popIndex]==pushA[top]){
top--;
popIndex++;
}
else{
if(pushIndex>=pushA.length)
return false;
else{
pushA[++top]=pushA[pushIndex];
pushIndex++;
}
}
}
return true;
}
(11)二叉搜索树的后序遍历序列
对于使用stack实现的得递归方法,不理解
(12)二叉树中和为某一值的路径(二)
此题递归与利用队列时间控件复杂度一致,且非递归实现起来麻烦,故仅练习了递归。
(13)二叉搜索树与双向链表
1、采用中序遍历的思想,这样便利结束才是有序的
2、利用head记录第一个节点,用pre记录遍历序列的前一个节点。注意当需要对pre进行更新时,pre为null,此时遍历序列的第一个节点记为head;
3、不要陷入要记录后一个节点的误区,无法做到。变通即pre.right指向现在的,现在的left指向pre。
递归方法实现:
private TreeNode head = null;
private TreeNode pre = null;
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree==null)
return null;
convert(pRootOfTree);
return head;
}
public void convert(TreeNode root){
if(root==null)
return ;
convert(root.left);
if(pre == null){
head = root;
}
else{
pre.right = root;
root.left = pre;
}
pre = root;
convert(root.right);
}
非递归方法:也可以看作用栈实现中序遍历
1、当指针不为空,或栈不为空都要继续进行 *** 作
2、利用while将当前指向的节点左子节点进栈,直到再无左子树
此指针为空,或进栈到再无左子树。进行出栈(此时对出栈节点 *** 作与递归的一致)
3、将指针指向当前出栈节点的右孩子,
因为此时此节点的左孩子一定已经进行过 *** 作,下一个要 *** 作的是右孩子
即每次都遍历到此节点最左, *** 作完成,指向当前节点右孩子,循环往复。
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree==null)
return null;
TreeNode head = null;
TreeNode pre = null;
Stack stack = new Stack();
while(pRootOfTree!=null||!stack.isEmpty()){
while(pRootOfTree!=null){
stack.push(pRootOfTree);
pRootOfTree = pRootOfTree.left;
}
TreeNode node = stack.pop();
if(pre==null)
head = node;
else{
pre.right = node;
node.left = pre;
}
pre = node;
pRootOfTree = node.right;
}
return head;
}
(14) 字符串的排列
一种更为简便的方法,利用字符串的子串获取与拼接。
递归传到现在的新串,剩余的字母,ArrayList
这里注意,ArrayList在函数中传递是地址的拷贝,不是仅仅参数的拷贝
public ArrayList Permutation(String str) {
ArrayList result = new ArrayList();
if(str==null||str.length()==0)
return null;
newString(str,"",result);
return result;
}
public void newString(String str,String newstr,ArrayList result){
if(str.length()==0){
if(!result.contains(newstr.toString()))
result.add(newstr.toString());
return ;
}
for(int i = 0;i
(15)最小的K个数
本题可利用三种方法实现:堆排序,有控制的快排,冒泡
对于堆排序思想:要用大顶推,因为堆顶的值是方便获取的,每次要看是不是前4小,就要看是不是比目前进堆的最大值还小,故要用大顶堆。
/*
这里采用优先队列的思想(大顶堆)
维护一个大顶堆,每次加入元素后如果多余k个就删除最大的
所有加入一遍后就剩下了k个最小的。
PriorityQueue的用法
大顶堆 new PriorityQueue((o1,o2)->(o2-o1));
小顶堆 new PriorityQueue< >();
自定义 Queue priorityQueue = new PriorityQueue<>(new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
*/
public ArrayList GetLeastNumbers_Solution(int [] input, int k){
ArrayList res = new ArrayList();
if(input.length==0||k==0)
return res;
Queue queue = new PriorityQueue((o1,o2)->(o2-o1));
for(int i=0;i
(16) 数据流中的中位数
提议目的理解清楚
ArrayList的add可以在对应位置添加(即插入元素)
private ArrayList res = new ArrayList();
public void Insert(Integer num) {
int index = 0;
if(res.isEmpty())
res.add(num);
else{
while(index
(17)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)