13.调整数组顺序使奇数位于偶数前面
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
(思路:是一个类似与快速排序,的思路,但快速排序是不稳定的。要保证,偶数和基数的相对位置稳定)
public void reOrderArray(int [] array) {
int n=0;//指向要被交换的位置,始终位于偶数串的第一位
int k=0;//记录连续的偶数串长度
for(int i=0;i<array.length;i++){//其中i就是遍历整个数组,走到偶数,就继续往前走,并记录走过偶数的个数,遇到奇数就将该基数,放到n所在位置,然后将整个偶数串后移一位。
if((array[i]&1)==0){//计算遍历到i位置,一共有多少个偶数
k++;//
}
if((array[i]&1)==1){//当为级数
int t=array[i];
int p=k;
while(p>0){//偶数串总体移动,保持相对位置不变
array[n+p]=array[n+p-1];//整个偶数串,向后移。
p--;
}
array[n]=t;//把奇数和需要被交换的位置
n++;//被交换位置向前移动。
}
}
}
输入一个链表,输出该链表中倒数第k个结点。
(思路很简单,两个指针都指向头节点,然后让其中一个向前跑k-1次,然后,后边的指针开始跟着跑,直到前面指针的next 是空,则后面指针的位置就是倒数第k个元素)
public ListNode FindKthToTail(ListNode head,int k) {
ListNode p=head;//后起步的指针
ListNode pre=head;//先起步的指针
if(k<=0)return null;//非法的k
while(k>1&&pre!=null){//让pre先走k-1步,
pre=pre.next;
k--;
}
if(pre==null){//整个链不足k个,返回空
return null;
}else{
while(pre.next!=null){//pre走k-1之后,p和pre一起走。
pre=pre.next;
p=p.next;
}
return p;
}
}
15. 反转链表
输入一个链表,反转链表后,输出链表的所有元素。
15.1(思路:将整个链放入一个栈,放完之后,出栈,然后根据出栈的顺序重新连接一条链就好了)
public ListNode ReverseList(ListNode head) {
Stack<ListNode> stack=new Stack<ListNode>();
while(head!=null){//全部放入栈
stack.push(head);
head=head.next;
}
if(!stack.isEmpty()){//栈不为空的情况下
ListNode last=stack.pop();//last指针指向第一个出<span style="line-height: 25.2px; font-family: arial, STHeiti, 'Microsoft YaHei', 宋体;">栈</span>的元素
ListNode first=last;//新的first指针也指向第一个出栈的元素
while(!stack.isEmpty()){
last.next=stack.pop();//last的下一个元素等于下一个弹出的元素
last=last.next;//last指针指向最新的弹出的元素
}
last.next=null;//循环之后,last位于最后一个元素,将最后一个元素的next置为空。
return first;//返回新链表的头
}else{//栈为空,返回空
return null;
}
}
15.2用三个指针来,来操作,这样节省空间。
public ListNode ReverseList(ListNode head) {
ListNode pre=null;
ListNode hnext=null;
while(head!=null){
hnext=head.next;
head.next=pre;
pre=head;
head=hnext;
}
return pre;
}
16.合并两个排序的链表
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
16.1非递归方法
(思路:思路较简单)
public ListNode Merge(ListNode list1,ListNode list2) {
ListNode list3=null;
ListNode listHead=null;
if(list1!=null&list2!=null){
if(list1.val<=list2.val){//将返回链表的头指针放在两个链表中值小的头上。
list3=new ListNode(list1.val);
listHead=list3;
list1=list1.next;
}else if(list2.val<list1.val){
list3=new ListNode(list2.val);
listHead=list3;
list2=list2.next;
}
//一次循环,两个链表元素一次比较,值较小的接到,返回链表后面,知道其中一个链表走完
while(list1!=null&&list2!=null){
if(list1.val<=list2.val){
list3.next=list1;
list3=list3.next;
list1=list1.next;
}else{
list3.next=list2;
list3=list3.next;
list2=list2.next;
}
}
if(list1==null){//将没有遍历完的链表的剩余部分接到,返回链表的后面
list3.next=list2;
}else if(list2==null){
list3.next=list1;
}
return listHead;
}else if(list1==null&&list2!=null){
listHead=list2;
}else if(list2==null&&list1!=null){
listHead=list1;
}
return listHead;
}
16.2递归的方法
public ListNode Merge(ListNode list1,ListNode list2) {
if(list1==null){
return list2;
}else 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:我们约定空树不是任意一个树的子结构)
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root1==null||root2==null){
return false;
}
if(root1.val==root2.val){//一旦当前节点相同,便调用<pre name="code" class="java" style="color: rgb(51, 51, 51); font-size: 14px; line-height: 22.4px;">isChildTree()方法,查看root2是否是root1的子树
boolean result=Solution.isChildTree(root1, root2);if(!result){
boolean res1=HasSubtree(root1.right,root2);boolean res2=HasSubtree(root1.left, root2);return res2||res1;}else{return true;}}else{boolean res1=HasSubtree(root1.right,root2);boolean res2=HasSubtree(root1.left, root2);return res2||res1;} } public static boolean isChildTree(TreeNode root1,TreeNode root2){// 该方法用来判断 两个相同根的树,root2是否是root1的子树 boolean result=false; if(root2==null){ return true; }else if(root1==null){ return false; } if(root1.val!=root2.val){ return false; }else{boolean res1= isChildTree(root1.right,root2.right);boolean re2=isChildTree(root1.left, root2.left);result=res1&&re2;return result; } } 18. 二叉树的镜像 操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:
二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ 11 9 7 5
public void Mirror(TreeNode root) {
if(root!=null){
Mirror(root.left);
Mirror(root.right);
TreeNode temp=root.left;
root.left=root.right;
root.right=temp;
}
}
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.
public ArrayList<Integer> printMatrix(int [][] matrix) {
ArrayList<Integer> list=new ArrayList<Integer>();
if(matrix.length==0){
return null;
}else if(matrix.length==1){
for(int j=0;j<matrix[0].length;j++){
list.add(matrix[0][j]);
}
}else if(matrix[0].length==1){
for(int i=0;i<matrix.length;i++){
list.add(matrix[i][0]);
}
}else{
int k=matrix.length<=matrix[0].length?matrix.length:matrix[0].length;
double t=((double)k)/2;
int x=0;
while(t>0){
if(k-x*2>1){
for(int i=x;i<matrix[0].length-x-1;i++){
list.add(matrix[x][i]);
}
for(int i=x;i<matrix.length-x-1;i++){
list.add(matrix[i][matrix[0].length-x-1]);
}
for(int i=matrix[0].length-x-1;i>x;i--){
list.add(matrix[matrix.length-x-1][i]);
}
for(int i=matrix.length-x-1;i>x;i--){
list.add(matrix[i][x]);
}
x++;
t--;
}else{
if(matrix.length>=matrix[0].length){
for(int i=x;i<matrix.length-x;i++){
list.add(matrix[i][x]);
}
}else{
for(int i=x;i<matrix[0].length-x;i++){
list.add(matrix[x][i]);
}
}
x++;
t--;
}
}
}
return list;
}
20.包含min函数的栈
定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
(思路:一个min栈用来存储当前最小的数,该栈栈顶始终是当前最小。出栈操作的时候,判断当前最小元素被弹出,若当前最小弹出,那么min栈也弹出,此时当前最小,依旧是min栈的栈顶)
public class Solution {
Stack<Integer> stack=new Stack<Integer>();
Stack<Integer> min =new Stack<Integer>();
public void push(int node) {
int minn=Integer.MAX_VALUE;
if(!min.isEmpty()){
minn=min.peek();
}
stack.push(node);
if(node<=minn){
minn=node;
min.push(node);
}
}
public void pop() {
int i=stack.pop();
if(i==min.peek()){
min.pop();
}
}
public int top() {
return stack.peek();
}
public int min() {
return min.peek();
}
}