# 基础算法记录四

## 字符串单词和标点符号顺序提取，禁止用split

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* 顺序提取字符串{Oh, a good day!}输出{"Oh",",","a","good","day","!"}
* @author Shinelon
*
*/
public class TestSplitString {
public static void main(String [] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
TestSplitString test = new TestSplitString();
String[] rs = test.dataSegement(str);
for(int i=0;i<rs.length;i++) {
System.out.println(rs[i]);
}
}

public String [] dataSegement(String str) {
char[] array = str.toCharArray();
List<String> list = new ArrayList<>();
int index = 0;
for(int i=0;i<array.length;i++) {
if(array[i]>='A'&&array[i]<='Z'||array[i]>='a'&&array[i]<='z') {

}else if(array[i]==' ') {
String string = str.substring(index,i);
index = i+1;

}else {
String string1 = str.substring(index,i);
String string2 = str.substring(i,i+1);
if(i+1<array.length&&array[i+1]==' ') {
index = i+2;
i++;
}
index = i+1;

}
}
String[] rs = new String[list.size()];
for(int i=0;i<list.size();i++) {
rs[i] = list.get(i);
}

return rs;
}
}


## 京东笔试题目：找出X*Y=某数 X奇数Y偶数，Y最小偶数 注意用Long，我这里没有。因为最大数2^63

import java.util.Scanner;
/**
* JD笔试
* 找出X*Y=某数  X奇数Y偶数，Y最小偶数  注意用long。因为最大数2^63
* @author Shinelon
*
*/
public class FindNum {
public static void main(String [] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();

long[] nums = new long[n];
for(int i=0;i<n;i++) {
nums[i]=sc.nextLong();
}
sc.close();
FindNum find = new FindNum();
find.findRs(nums);
}

public void findRs(long [] nums) {
for(int j=0;j<nums.length;j++) {
if(nums[j]%2!=0) {
System.out.println("No");
return ;
}else {
long temp = nums[j]-1;
while(nums[j]%temp!=0&&temp>=1) {
temp -=2;
}
long left = temp;
long right = nums[j]/temp;
System.out.println(left+" "+right);
}
}
}
}


## 判断栈的正确序列问题

import java.util.Scanner;
import java.util.Stack;
/**
* 判断栈的正确序列问题 12345 45321 45123...
* @author Shinelon
*
*/
public class Solution {

public static void main(String [] args){
Solution solution = new Solution();
Scanner sc = new Scanner(System.in);
int size = sc.nextInt();
int [] pushA = new int[size];
int [] popA = new int[size];
for(int i=0;i<size;i++) {
pushA[i] = sc.nextInt();
}
for(int i=0;i<size;i++) {
popA[i] = sc.nextInt();
}
Solution s = new Solution();
boolean rs = s.IsPopOrder(pushA, popA);
System.out.println(rs);
}
/**
* 用一个辅助栈，假设序列是正确的，根据序列模拟出栈，若辅助栈空而序列遍历完，说明没矛盾
* @param pushA
* @param popA
* @return
*/
public boolean IsPopOrder(int [] pushA,int [] popA) {

Stack<Integer> temp = new Stack<>();
int k=0;
for(int i=0;i<pushA.length;i++) {
temp.push(pushA[i]);
if(temp.peek()==popA[0]) {
temp.pop();
k++;
}
}

while(!temp.isEmpty()) {
int t =temp.pop();
if(t==popA[k]) {
k++;
}
}

if(k==popA.length) {
return true;
}else {
return false;
}

}

public int getIndexFromA(int [] A,int num) {
for(int j=0;j<A.length;j++) {
if(num==A[j]) {
return j;
}
}
return -1;
}

}


## 移动0 比如 042013 变为421300

import java.util.Scanner;
/**
* 移动0，保留原来顺序，比如 0 1 4 3 0 为 1 4 3 0 0
* @author Shinelon
*
*/
public class MoveZero {
public static void main(String [] args) {
Scanner sc = new Scanner(System.in);
MoveZero move = new MoveZero();
int n = sc.nextInt();
int nums [] = new int[n];
for(int k=0;k<n;k++) {
nums[k] = sc.nextInt();
}
sc.close();

move.moveZeroes(nums);
for(int k=0;k<n;k++) {
System.out.println(nums[k]);
}
}

public void moveZeroes(int[] nums) {
int count_zero = 0;
for(int i=0;i<nums.length;i++) {
if(nums[i]==0) {
count_zero++;
}else if(count_zero>0){
nums[i-count_zero] = nums[i];
}
}
for(int j=nums.length-count_zero;j<nums.length;j++) {
nums[j] = 0;
}
}
}


## 合并有序链表

public class MergerTwoLinks {
static ListNode l1;
static ListNode l2;
class ListNode{
int val;
ListNode next;
}

public static void main(String [] args) {
merge.initList();

ListNode rs = merge.mergeTwoLists(l1, l2);

while(rs!=null) {
System.out.print(rs.val);
rs = rs.next;
}
}
/**
* 思路，将两个链表表头小的节点作为合并后的头结点，然后指针后移，循环比较两个链表的头节点
* 小的插到合并后的链表后面直到旧的链表遍历结束
* @param l1
* @param l2
* @return
*/
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode temp = null;
l1 = l1.next;
l2 = l2.next;
}
while(l1!=null||l2!=null) {

if(l1==null) {
temp.next = l2;
//退出循环，不然死循环
break;
}else if(l2==null){
temp.next = l1;
break;
}else {
if(l1.val<=l2.val) {
temp.next = l1;
temp = temp.next;
l1 = l1.next;
}else {
temp.next = l2;
temp = temp.next;
l2 = l2.next;
}
}

}
}

public void initList() {
l1 = new ListNode();
l1.val=1;

l2 = new ListNode();
l2.val=1;
}

public void addNode(ListNode l,int x) {
while(l.next!=null) {
l = l.next;
}
l.next = new ListNode();
l.next.val = x;
}

}


## 三数之和为0

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
/**
* 找出数组三数之和为0的元素，不重复，双指针
* @author Shinelon
*
*/
public class TestThreeNum {

public static void main(String [] args) {
Scanner sc = new Scanner(System.in);
TestThreeNum test = new TestThreeNum();
int n = sc.nextInt();
int [] nums = new int[n];
for(int i=0;i<n;i++) {
nums[i]=sc.nextInt();
}
sc.close();
//先排序
Arrays.sort(nums);
List<List<Integer>> rs = test.threeSum(nums);
System.out.println(rs.toString());
}

public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> outList = new ArrayList<>();
//如果大于0都是正数，不可能
if(nums[0]>0) {
return outList;
}
for(int i=0;i<nums.length-2;i++) {
//去除重复
if(i>0&&nums[i]==nums[i-1]) {
continue;
}
int j=i+1;
int k=nums.length-1;
while(j<k) {
if(nums[k]+nums[j]+nums[i]>0) {
k--;
}else if(nums[k]+nums[j]+nums[i]<0){
j++;
}else {
List<Integer> list = new ArrayList<>();
//继续遍历
k--;
j++;
//去除重复
while(j<k&&nums[j]==nums[j-1]) {
j++;
}
//去除重复
while(j<k&&nums[k]==nums[k+1]) {
k--;
}

}
}
}
return outList;

}
}


## 最长不重复字串

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
* 最长不重复子串O(n)
* HashMap，key为字符，value为索引。当map中不存在时，直接放入，否则取出上一个索引
* 当前减去上一个索引即为当前不重复的最长长度，然后从上一个重复的数的下一个索引开始新一轮比较，
* 也就是去除重复因素的影响，将开始start+1索引。若不存在，放入之后更新长度值，也就是-start+1
* @author Shinelon
*
*/
public class TestMaxChildString {

public static void main(String [] args) {
TestMaxChildString test = new TestMaxChildString();
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
sc.close();
int rs = test.lengthOfLongestSubstring(s);
System.out.println(rs);
}

public int lengthOfLongestSubstring(String s) {
char [] c = s.toCharArray();
Map<Character,Integer> map = new HashMap<>();
int max=0;//最大值
int start=0;//寻找不重复字串长度开始的索引
for(int i=0;i<c.length;i++) {
if(map.containsKey(c[i])) {
//temp>=start，说明在寻找的合法范围内
int temp =map.get(c[i]);
if(temp>=start) {
//更新，两个之间的差值即为不重复长度
max = Math.max(i-temp,max);
//后移一位，因为前面已经重复了，构造新的不重复串并继续比较，后面可能出现更长的不重复
start = temp+1;
//更新当前的索引，消除前面那个重复数的影响，因为构造的是不重复的新串
map.put(c[i], i);
}else {//不存在，则放入并更新值
map.put(c[i], i);
int rs = i-start+1;
max = Math.max(max, rs);
}
}else {
map.put(c[i], i);
int rs = i-start+1;
max = Math.max(max, rs);
}
}
return max;
}
}


• 评论

• 上一篇
• 下一篇