13.调整数组顺序使奇数位于偶数
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
题目思路
该题有很多的解法,这里提的是一种比较容易想到的思路,及类似于冒泡排序。当前面是为偶数后面是为奇数则交换顺序。当然该题还包括了插入排序,快速、归并等各种方法,在时间复杂度上有优势,为了熟悉常见排序算法,需要去学习一下;
代码
public class Solution {
public void reOrderArray(int [] array) {
int temp=0;
boolean flag=false;
for(int i=0;i
14.链表中倒数第K个节点
题目描述
输入一个链表,输出该链表中倒数第k个结点。
题目思路
该题采用新建一个List的方式,将链表中的值一次加入到List,因为List也是有序的,故可以计算其下标通过LIst的get方法取的相应位置的值(arr.size()-k).同时需考虑多种情况,k小于等于零时,k大于链表大小时,都需返回null;
代码
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
import java.util.ArrayList;
import java.util.List;
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
if(k<=0||head==null){
return null;
}
List arr=new ArrayList();
while(head.next!=null){
arr.add(head);
head=head.next;
}
arr.add(head);
return arr.size()>=k?arr.get(arr.size()-k):null;
}
}
15.反转链表
题目描述
输入一个链表,反转链表后,输出链表的所有元素。
题目思路
该题目本来想着是照上一题的思路,先将其存入一个List里面,而后从后往前依次建立单链表。无奈按此思路写出来不知道是代码错了还是时间超了反正没通过。只能另想他法,通过加入第三变量强行改变链表的指向问题。具体请看代码部分。
代码
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null){
return null;
}
if(head.next==null){
return head;
}
ListNode reverse=null;
ListNode tmp=null;
ListNode current=head.next;
head.next=null;
while(current.next!=null){
tmp=current.next;
current.next=head;
head=current;
current=tmp;
}
current.next=head;
reverse=current;
return reverse;
}
}
16.合并两个排序链表
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
题目思路
一开始想到的是插入排序的思想,撸出来后果不其然,复杂过高(因为插排没有考虑其中一个原始链表的有序性),则考虑递归的思路。递归这个东西,好像说不太清,自己看代码。该方法也可非递归实现,核心思路为每次从list1和list2里面取一个元素,因为list1和list2都是有序的,则我们可以从头取至尾。
代码
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
if(list1==null){
return list2;
}
if(list2==null){
return list1;
}
if(list1.val<=list2.val){
list1.next=Merge(list1.next,list2);
return list1;
}else{
list2.next=Merge(list1,list2.next);
return list2;
}
}
}
17.树的子结构
题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
题目思路
首先得明白一个事情,则凡是涉及到二叉树的编程一般得用递归的思路。该题目分两步走。
要查找树A中是否存在和树B结构一样的子树,
可以分成两步:
- 第一步在树A中找到和B的根节点的值一样的结点R;
- 第二步再判断树A中以R为根结点的子树是不是包含和树B一样的结构。
第一步在树A中查找与根结点的值一样的结点,这实际上就是树的遍历。递归调用HasSubTree遍历二叉树A。如果发现某一结点的值和树B的头结点的值相同,则调用DoesTreeHavaTree2,做第二步判断。第二步是判断树A中以R为根结点的子树是不是和树B具有相同的结构。
代码
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
boolean flag=false;
if(root1!=null&&root2!=null){
if(root1.val==root2.val){
flag=Subtree(root1,root2);
}if(!flag){
flag=HasSubtree(root1.left,root2)||HasSubtree(root1.right,root2);
}
}
return flag;
}
private boolean Subtree(TreeNode root1,TreeNode root2){
if(root2==null){
return true;
}
if(root1==null){
return false;
}
if(root1.val!=root2.val){
return false;
}else{
return Subtree(root1.left,root2.left)&&Subtree(root1.right,root2.right);
}
}
}
18.二叉树镜像
题目描述
操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:
二叉树的镜像定义:
题目思路
该题看起来比较复杂,但还是按照老思路。一旦涉及到二叉树的编程,一定要想到递归的思路。递归的调换左右孩子的即可。
代码
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public void Mirror(TreeNode root) {
if(root==null) return;
TreeNode temp=null;
if(root.left!=null||root.right!=null){
temp=root.left;
root.left=root.right;
root.right=temp;
}
if(root.left!=null){
Mirror(root.left);
}
if(root.right!=null){
Mirror(root.right);
}
}
}
19.顺时针打印矩阵
题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
题目思路
该题目确实比较费劲,先按自己暴力思路撸了会代码,发现太复杂了。然后放弃了,想去看别人的代码,发现也挺复杂的。于是决定继续撸自己的代码,意外的是还真成了。第一种情况:行列都为偶数,先打印一行(行不变列累加),打印一列(起始行加1,列不变,行累加),行不变列递减(行为最后一行,列为最后一列),列不变行递减。但每走一圈它的边界条件也在边,所以需设置四个变量作为边界条件。第二种行为奇数或列为奇数或两个都为奇数。这个时候会出现在最后的时候只打印一行或一列或一个数。具体请看代码。
代码
import java.util.ArrayList;
public class Solution {
public ArrayList al=null;
public ArrayList printMatrix(int [][] matrix) {
al=new ArrayList();
int wide=matrix[0].length;
int high=matrix.length;
if(wide<=high){
int n=wide/2;
huatu(n,wide,high,matrix);
if(wide%2==1){
for(int i=n;ibb;b--){
al.add(matrix[a][b]);
}for(int a=ba,b=bb;a>aa;a--){
al.add(matrix[a][b]);
}
aa++;
bb++;
ab--;
ba--;
}
}
}
20.包含min函数的栈
题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
题目思路
该题目是对栈知识的考查,及出栈入栈、栈顶元素、判空、栈的扩容(数组的扩容)等。栈其实就是一个受限制的数组或者链表。这里有个关键的细节就是引进了一个系统栈来保存最小值。因为最小值会受出栈入栈的影响,所以用一个对应的辅助栈可以降低时间复杂度。具体妙处可以看代码体会。
代码
import java.util.Stack;
import java.util.Arrays;
public class Solution {
private int size=0;
private int min=Integer.MAX_VALUE;
private Stack minStack=new Stack();
private Integer[] elements=new Integer[10];
public void push(int node) {
ensureCapacity(size+1);
elements[size++]=node;
if(node <= min){
minStack.push(node);
min = minStack.peek();
}else{
minStack.push(min);
}
}
private void ensureCapacity(int size){
int len=elements.length;
if(size>len){
int newlen=(len*3)/2+1;
elements = Arrays.copyOf(elements,newlen);
}
}
public void pop() {
Integer top=top();
if(top != null){
elements[size-1] = (Integer) null;
}
size--;
minStack.pop();
min=minStack.peek();
}
public int top() {
if(!empty()){
if(size-1>=1) return elements[size-1];
}
return (Integer)null;
}
public boolean empty(){
return size==0;
}
public int min() {
return min;
}
}