剑指offer(简单到复杂顺序题解)
21.调整数组顺序使奇数位于偶数前面
双指针法
class Solution {
public int[] exchange(int[] nums) {
int temp;
int i=0,j=nums.length-1;
while(i<j){
while(i<j && nums[i]%2==1)i++;
while(i<j && nums[j]%2==0)j--;
temp = nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
return nums;
}
}
52.两个链表的第一个公共节点
假设A链表的长度为a,B链表的长度为b,公共部分的长度为c。
A链表遍历完a的距离再去遍历 b-c,走过节点数为 a+(b-c);
B链表遍历完b的距离再去遍历 a-c,走过节点数为 b+(a-c);
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode A=headA;
ListNode B=headB;
while(A!=B){
A = A!=null ? A.next : headB;
B = B!=null ? B.next : headA;
}
return A;
}
}
50.第一个只出现一次的字符
利用哈希表,第一次遍历,记录出现字符的次数,大于一次为false,出现一次为ture。第二次遍历,返回第一次个ture对应的键。
class Solution {
public char firstUniqChar(String s) {
HashMap<Character,Boolean> h =new HashMap<>();
char[] sc =s.toCharArray();
for(char c:sc)
h.put(c,!h.containsKey(c));
for(char c:sc)
if(h.get(c)) return c;
return ' ';
}
}
42.连续子数组的最大和
class Solution {
public int maxSubArray(int[] nums) {
int res =nums[0];
for(int i=1;i<nums.length;i++){
nums[i]+=Math.max(nums[i-1],0);
res=Math.max(nums[i],res);
}
return res;
}
}
18.删除链表的节点
1.特例化处理:当删除节点为头结点时,直接返回head.next
2.初始化:ListNode pre=head,cur=head.next;
3.定位节点:当cur节点值为空,或者cur节点值为val时 跳出
保存当前节点的索引 pre=cur; cur=cur.next;
4.删除节点
5.返回值:返回链表头部
class Solution {
public ListNode deleteNode(ListNode head, int val) {
if(head.val==val) return head.next;
ListNode pre =head,cur=head.next;
while(cur!=null && cur.val!=val){
pre=cur;
cur=cur.next;
}
if(cur!=null)pre.next=cur.next;
return head;
}
}
55.平衡二叉树(递归)
后续遍历判断
class Solution {
public boolean isBalanced(TreeNode root) {
return recur(root)!=-1;
}
private int recur(TreeNode root){
if(root==null)return 0;
int left=recur(root.left);
if(left==-1)return -1;
int right=recur(root.right);
if(right==-1)return -1;
return Math.abs(left-right)<2?Math.max(left,right)+1:-1;
}
}
28.对称的二叉树(递归)
class Solution {
public boolean isSymmetric(TreeNode root) {
return root==null?true:recur(root.left,root.right);
}
boolean recur(TreeNode L,TreeNode R){
if(L==null&&R==null) return true;
if(L==null || R==null || L.val!=R.val)return false;
return recur(L.left,R.right)&& recur(L.right,R.left);
}
}
65.不用加减乘除做加法
class Solution {
public int add(int a, int b) {
while(b!=0){
int c=(a&b)<<1;
a^=b;
b=c;
}
return a;
}
}
30.包含min函数的栈
class MinStack {
Stack<Integer>A,B;
/** initialize your data structure here. */
public MinStack() {
A=new Stack<>();
B=new Stack<>();
}
public void push(int x) {
A.add(x);
if(B.empty() || B.peek()>=x)
B.add(x);
}
public void pop() {
if(A.pop().equals(B.peek()))
B.pop();
}
public int top() {
return A.peek();
}
public int min() {
return B.peek();
}
}
40.最小的K个数
先排序,再找
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
int[] vec= new int[k];
Arrays.sort(arr);
for(int i=0;i<k;i++){
vec[i]=arr[i];
}
return vec;
}
}