回文/相加/排序
public ListNode ReverseList(ListNode head) {
ListNode p=head;
ListNode pre=null;
while(p!=null)
{
ListNode q=p.next;
p.next=pre;
pre=p;
p=q;
}
return pre;
}
1、特殊情况{1}:p都是指向null(换个头)
2、特殊情况 null:while 跳过,直接输出 pre=null
3、while(p!=null):p每次都是截断后的下一个。pre是结尾。所以在while中取q。
public ListNode reverseBetween (ListNode head, int m, int n) {
//1.{} {1} m<=n
if(head==null||head.next==null||m==n)
return head;
//2.从头开始
ListNode pre=null;
ListNode p=head;
ListNode PRE=null;//【ERRPR】PRE=head
int count=1;
//3.从中间开始(默认m
if(m!=1){
while(count!=m){
pre=p;
p=p.next;
count++;
}
PRE=pre;
pre=p;
p=p.next;count++;
}
while(count!=n+1){//【ERRPR】n+1
ListNode q=p.next;
p.next=pre;
pre=p;
p=q;
count++;
}
if(PRE!=null) {
PRE.next.next=p;
PRE.next=pre;
return head;
}
else{
head.next=p;//【ERRPR】PRE.NEXT
return pre;
}
}
public ListNode Merge(ListNode list1,ListNode list2) {
ListNode p1=list1;
ListNode p2=list2;
ListNode h=new ListNode(-1);//定义表头
ListNode q=h;
while(p1!=null&&p2!=null){
if(p1.val<=p2.val){
q.next=p1;//h表和q1,q2表还有联系,前置节点没有断,没关系
p1=p1.next;
}
else{
q.next=p2;
p2=p2.next;
}
q=q.next;
q.next=null;
}
if(p2!=null)//直接赋值
p1=p2;
q.next=p1;
return h.next;//直接这样输出就行
}
1、HashSet
import java.util.*;
public class Solution {
public boolean hasCycle(ListNode head) {
if(head==null||head.next==null)
return false;
Set<ListNode> set=new HashSet<ListNode>();
ListNode p=head;
while(p!=null){
if(set.contains(p))
return true;
set.add(p);
p=p.next;
}
return false;
}
}
2、《快慢指针》fast快走两步,fast和slow有坏总会相遇
public boolean hasCycle(ListNode head) {
//1.{},{1}
if(head==null||head.next==null)
return false;
//2.{1,2,null}+{1,2,3,4..}
ListNode fast=head;
ListNode slow=head;
while(fast!=null&&fast.next!=null)//【ERROR】判断条件是为进出服务的
{
fast=fast.next.next;//是一直快走两步
slow=slow.next;
if(fast==slow)
return true;
}
return false;
}
HashSet
import java.util.*;
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead) {
if(pHead==null||pHead.next==null)
return null;
Set<ListNode> set=new HashSet<ListNode>();
ListNode p=pHead;
while(p!=null)
{
if(set.contains(p))
return p;
set.add(p);
p=p.next;
}
return null;
}
}
一个指针提前k几步另一个再走
public ListNode FindKthToTail (ListNode pHead, int k) {
//特殊情况
if(pHead==null)
return null;
ListNode p=pHead;
int count=1;
//【p!=null要放前面限制k】
//【count<=k】
while(p!=null&&count<===k){
count++;
p=p.next;
}
if(count<=k&&p==null)//【ERROR拉下了这种情况】
return null;
ListNode pre=pHead;
while(p!=null){
pre=pre.next;
p=p.next;
}
return pre;
}
区别于输出:因为用到了前置结点
public ListNode removeNthFromEnd (ListNode head, int n) {
// 特殊情况
if(head==null)
return null;
ListNode p=head;
int count=1;
ListNode h=new ListNode(-1);//【因为要用到前置】
h.next=head;//【不是用h走的】
ListNode pre=h;
while(p!=null&&count<=n){//【判断条件是一样的:因为多了前置,所以这里不变】
p=p.next;
count++;
}
if(p==null&&count<=n)
return null;
while(p!=null)//【ERRPR:不用判断p.next】
{
p=p.next;
pre=pre.next;
}
pre.next=pre.next.next;
return h.next;
}
画图
//特殊情况:{}
if(pHead1==null||pHead2==null)
return null;
ListNode p1=pHead1;int k1=0;
ListNode p2=pHead2;int k2=0;
while(p1!=null){
p1=p1.next;
k1++;
}
while(p2!=null){
p2=p2.next;
k2++;
}
p1=pHead1;
p2=pHead2;
if(k1>k2){
p1=pHead1;
for(int i=1;i<=k1-k2;i++)
p1=p1.next;
}
if(k1<k2){
for(int i=1;i<=k2-k1;i++)
p2=p2.next;
}
while(p1!=null&&p2!=null){
if(p1==p2)
return p1;
p1=p1.next;
p2=p2.next;
}
return null;
}
一个指针提前k几步另一个再走
提示:这里可以添加计划学习的时间
提示:这里可以添加计划学习的时间
提示:这里可以添加计划学习的时间
public ListNode oddEvenList (ListNode head) {
if(head==null)
return null;
int count=1;
ListNode h=head;
ListNode pHead=new ListNode(-1);ListNode p=pHead;
ListNode qHead =new ListNode(-1);ListNode q=qHead;
while(h!=null)
{
if(count%2!=0){
p.next=h;h=h.next;//【ERROR:h要紧跟后面】
p=p.next;
p.next=null;
}
else{
q.next=h;h=h.next;//【ERROR:h要紧跟后面】
q=q.next;
q.next=null;
}
count++;
}
p.next=qHead.next;
return pHead.next;
}
自己走:不合适就删掉下一个
public ListNode deleteDuplicates (ListNode head) {
//特殊情况{} {x}
if(head==null||head.next==null)
return head;
//一般情况
ListNode p=head;
while(p.next!=null)
{
if(p.val==p.next.val)
p.next=p.next.next;
else
p=p.next;
}
return head;
}
1、前置节点:信任了再加上
2、HashMap记数:次数大于1 的全部删除
public ListNode deleteDuplicates (ListNode head) {
if(head==null||head.next==null)
return head;
HashMap<Integer,Integer>map=new HashMap<Integer,Integer>();
ListNode p=head;
while(p!=null){
if(map.containsKey(p.val))
map.put(p.val,map.get(p.val)+1);
else
map.put(p.val,1);
p=p.next;
}
ListNode h=new ListNode(1);
h.next=head;
p=h;
while(p.next!=null)
{
if(map.get(p.next.val)>1)
p.next=p.next.next;//【用p自己就行,不用另外定义】
else
p=p.next;
}
return h.next;
}
元素升序的、无重复数字
public int search (int[] nums, int target) {
int left=0;
int right=nums.length-1;
while(left<=right)//【1.<=】
{
int mid=(left+right)/2;
if(nums[mid]==target)
return mid;
if(target>nums[mid])
left=mid+1;
else
right=mid-1;
}
return -1;
}
每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序
for(int[] arr:array)//数组的东西
{
int left=0;
int right=arr.length-1;
while(left<=right)
{
int mid=(left+right)/2;
if(target==arr[mid])
return true;
if(target>arr[mid])
left=mid+1;
else
right=mid-1;
}
}
return false;
}
每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序
public int findPeakElement (int[] nums) {
int left=0;
int right=nums.length-1;
while(left<right)
{
int mid=(left+right)/2;
if(nums[mid]>nums[mid+1])//【mid-1有<0的风险,所以和mid+1比较】
right=mid;//【区间内递减,right变成可能的峰值】
else
left=mid+1;//【区间内增,left变成可能的峰值】
}
return right;//【输出left/right都行】
}
分[分解]-治[修补] 归并排序
public class Solution {
int count=0;//全局操作的参数
//0.程序入口
public int InversePairs(int [] array) {
if(array.length<2)
return 0;
mergesort(array,0,array.length-1);
return count;
}
//1,归并排序【递归】
public void mergesort(int []array,int left,int right)
{
//终止条件
if(left>=right)
return;
//递归操作(先序树)
int mid=left+(right-left)/2;///2
mergesort(array,left,mid);
mergesort(array,mid+1,right);
merge(array,left,mid,right);//在前一层级上收拾count(每组拍好了)
}
//2.收拾count
public void merge(int []array,int left,int mid,int right)
{
//1、左右数组重新排序组装到排序数组
int arr[]=new int[right-left+1];//排序数组
int index=0;//排序数组下标记
int l=left;//左待排序数组首下标
int r=mid+1;//右待排序数组首下标
//left---mid;mid+1---right(l--r)
while(l<=mid&&r<=right)
{
//l)一开始就小于r时
if(array[l]>array[r])
{
arr[index]=array[r];
r++;
count+=mid+1-l;
count=count%1000000007;
}
//2)L比r大
else
{
arr[index]=array[l];
l++;
}
index++;
}
while(l<=mid)
arr[index++]=array[l++];
while(r<=right)
arr[index++]=array[r++];
//2、排序后的数组复制到原数组
int s=left;//重新赋值原赋数组
for(int t:arr)
array[s++]=t;
}
}
import java.util.*;
public class Solution {
public void merge(int A[], int m, int B[], int n) {
if(m==0){
for(int i=0;i<n;i++)//【不可以A=B】
A[i]=B[i];
return;
}
if(n==0)
return;
int C[]=new int[m+n];//可以用形参定义数组大小
int c=0;
int a=0;
int b=0;
while(a<=m-1&&b<=n-1){
if(A[a]<=B[b]){
C[c]=A[a];
a++;
}
else{
C[c]=B[b];
b++;
}
c++;
}
while(a<=m-1){
C[c]=A[a];
a++;
c++;
}
while(b<=n-1){
C[c]=B[b];
b++;
c++;
}
for(int i=0;i<C.length;i++)
A[i]=C[i];
}
}
String和char数组的转换
import java.util.*;
public class Solution {
public boolean judge (String str) {
// write code here
if(str.length()<=1)
return true;
char c[]=str.toCharArray();
for(int i=0;i<=(c.length-1)/2;i++)//【i<=(c.length-1)/2】
{
if(c[i]!=c[c.length-1-i])
return false;
}
return true;
}
}
import java.util.*;
public class Solution {
public ArrayList<Interval> merge(ArrayList<Interval> intervals) {
ArrayList<Interval> list=new ArrayList<Interval>();
if(intervals.size()<=1)
return intervals;
//【集合元素的自定义排序:按照先排左再排右节点的方式排序】
Collections.sort(intervals,new Comparator<Interval>(){
public int compare(Interval a,Interval b)
{
if(a.start!=b.start)
return a.start-b.start;
else
return a.end-b.end;
}
});
int k=0;
//1、先放进去1个:index=k;
list.add(intervals.get(0));
for(int i=1;i<intervals.size();i++)
{
Interval x=list.get(k);
//2.再取下一个待比较的
Interval y=intervals.get(i);
//1)先比较有交集的
if(y.start<=x.end)
{
if(y.end<=x.end) //全部包含
continue;
else //部分包含
{
Interval temp=new Interval(x.start,y.end);
list.remove(k);
list.add(temp);
}
}
//2)没有交集的直接放进去
else
{list.add(y);
k++;
}
}
return list;
}
}
StringBuffer
import java.util.*;
public class Solution {
public String solve (String str) {
StringBuffer s=new StringBuffer();
s.append(str);
return s.reverse().toString();
}
}
队列
import java.util.*;
public class Solution {
public int maxLength (int[] arr) {
Queue<Integer>queue=new LinkedList<Integer>();
int max=0;
for(int i=0;i<arr.length;i++){
while(queue.contains(arr[i])){//【!while】
queue.poll();
}
queue.add(arr[i]);
max=Math.max(max,queue.size());
}
return max;
}
}
思想没看那
import java.util.*;
public class Solution {//思想没看
public int maxArea (int[] height) {
if(height.length<2)
return 0;
int area=0;//面积
int left=0;//左边
int high=height.length-1;//右边
while(left<high)
{
//比较:area和底*最小侧边
area=Math.max(area,(high-left)*Math.min(height[left],height[high]));
if(height[left]<height[high])//小的移动
left++;
else
high--;
}
return area;
}
}