public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextInt()) {//注意while处理多个case
int a = in.nextInt();
int b = in.nextInt();
System.out.println(a + b);
}
}
题意:二维数组从左至右递增,从上至下递增,给一个数判断是否在里面
思路:找到数组的规律,从左下角开始找最好,如果目标比他大,向右移动;如果比他小,向左移动。
public class Solution {
public boolean Find(int target, int [][] array) {
int a = array.length;
int b = array[0].length;
for(int i = a-1,j= 0;i>=0&&j<b;){
if(array[i][j]>target ){
i--;
}
else if(array[i][j]<target){
j++;
}
else{
return true;
}
}
return false;
}
}
public static String replaceSpace(StringBuffer str) {
int l = str.length();
int space = 0;
for(int i = 0;i<l;i++) {
if(str.charAt(i)==' ') {
space++;
}
}
space = 2*space;
str.setLength(l+space);
for(int i = l-1,j = l-1+space;i>=0;) {
if(str.charAt(i)!=' ') {
str.setCharAt(j, str.charAt(i));
i--;
j--;
}
else {
str.setCharAt(j,'0');
j--;
str.setCharAt(j,'2');
j--;
str.setCharAt(j,'%');
j--;
i--;
}
}
String res = str.toString();
return res;
}
import java.util.Stack;
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> res = new ArrayList<Integer>();
Stack<Integer> s = new Stack<Integer>();
while(listNode != null) {
s.push(listNode.val);
listNode = listNode.next;
}
while(!s.isEmpty()) {
res.add(s.pop());
}
return res;
}
}
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
if(stack2.isEmpty()){
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
}
public static int minNumberInRotateArray(int [] array) {
int len = array.length;
if (len == 0) {
return 0;
}
else {
int[] res = new int[2];
res = binary(0,len-1,array);
while(res[1] - res[0] !=1 && res[0] != -1){
res = binary(res[0],res[1],array);
}
if(res[0] == -1){
int min = array[0];
for(int i = 0;i<len;i++) {
if(min>array[i]) {
min = array[i];
}
}
return min;
}
else{
return array[res[1]]<array[res[0]]?array[res[1]]:array[res[1]];
}
}
}
public static int[] binary(int start, int end,int [] a){
int[] res1 = new int[2];
int mid = (start+end)/2;
if(a[mid] == a[start] && a[mid] == a[end]) {
res1[0] = -1;
res1[1] = -1;
return res1;
}else if(a[mid]>=a[start]){
res1[0] = mid;
res1[1] = end;
return res1;
}
else{
res1[0] = start;
res1[1] = mid;
return res1;
}
}
public static int Fibonacci(int n) {
int a = 0,b = 1,c;
if(n == 0) {
return 0;
}else {
for(int i =0;i<n-1;i++) {
c = a+b;
a = b;
b = c;
}
return b;
}
Fibonacci数列是这样定义的: F[0] = 0 F[1] = 1 for each i ≥ 2: F[i] = F[i-1] +
F[i-2] 因此,Fibonacci数列就形如:0, 1, 1, 2, 3, 5, 8, 13,
…,在Fibonacci数列中的数我们称为Fibonacci数。给你一个N,你想让其变为一个Fibonacci数,每一步你可以把当前数字X变为X-1或者X+1,现在给你一个数N求最少需要多少步可以变为Fibonacci数。
输入描述: 输入为一个正整数N(1 ≤ N ≤ 1,000,000)
输出描述: 输出一个最小的步数变为Fibonacci数"
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner i = new Scanner(System.in);
System.out.println(FibI(i.nextInt()));
}
public static int FibI(int n) {
int a = 0,b = 1,c;
while(true) {
if(n>=a && n<=b) {
break;
}
c = a+b;
a = b;
b = c;
}
return n-a>b-n?b-n:n-a;
}
}
题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
public static int JumpFloor(int target) {
if(target<=2) {
return target;
}
return JumpFloor(target-2) +JumpFloor(target-1);
题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
public static int JumpFloorII(int target) {
if(target<=2) {
return target;
}
int res = 0;
while(target>1) {
res += JumpFloorII(target-1);
target --;
}
return res+1;
}
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
public class Solution {
public int RectCover(int target) {
if(target<=2){
return target;
}
return RectCover(target-1)+RectCover(target-2);
}
}
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
public int NumberOf1(int n) {
int count = 0;
for (int i = 0; i < 32; i++)
{
int t = (n & 0x80000000 >>> i) >>> (31 - i);
if(t == 1){
count++;
}
}
return count;
}
public int NumberOf1(int n) {
int count = 0;
while(n!= 0){
count++;
n = n & (n - 1);
}
return count;
}
举个例子:一个二进制数1100,从右边数起第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
public double Power(double base, int exponent) {
double res=1.0;
if(exponent>=0){
for(int i=0;i<exponent;i++){
res =res*base;
}
}
else{
base = 1.0/base;
for(int i=0;i<-exponent;i++){
res =res*base;
}
}
return res;
}
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
public static void reOrderArray(int [] array) {
int len = array.length,j=0;
int[] res = new int[len];
res = array.clone();
for(int i=0;i<len;i++) {
if(res[i]%2!=0) {
array[j] = res[i];
j++;
}
}
for(int i=0;i<len;i++) {
if(res[i]%2==0) {
array[j] = res[i];
j++;
}
}
}
for (int i = 0; i < array.size();i++)
{
for (int j = array.size() - 1; j>i;j--)
{
if (array[j] % 2 == 1 && array[j - 1]%2 == 0) //前偶后奇交换
{
swap(array[j], array[j-1]);
}
}
}
}
题目描述 输入一个链表,输出该链表中倒数第k个结点。
public ListNode FindKthToTail(ListNode head,int k) {
ListNode r = head;
int l = 1;
if(head == null | k<0){
return null;
}
while(r.next != null){
r = r.next;
l++;
}
if(l<k)
return null;
for(int i =0;i<=l-k-1;i++){
head = head.next;
}
return head;
}
public ListNode FindKthToTail(ListNode head,int k) {
ListNode a = head;
ListNode b = head;
if(head == null|k<0){
return null;
}
int i = 0;
while(a!=null & i<k){
i++;
a = a.next;
}
if(i!=k){
return null;
}
while(a!=null){
b = b.next;
a = a.next;
}
return b;
}
输入一个链表,反转链表后,输出新链表的表头。
public ListNode ReverseList(ListNode head) {
if(head == null||head.next == null){
return head;
}
ListNode a = head;
int l = 1;
while(a.next!= null){
a = a.next;
l++;
}
ListNode res = a;
for(int i=l-2;i>=0;i--){
ListNode b = head;
for(int j=0;j<i;j++){
b = b.next;
}
ListNode C = new ListNode(b.val);
a.next = C;
a = a.next;
}
return res;
}
public ListNode ReverseList(ListNode head) {
ListNode pre = null;
ListNode behind ;
if(head == null||head.next == null){
return head;
}
while(head!=null){
behind = head.next;
head.next = pre;
pre = head;
head = behind;
}
return pre;
}
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
public static ListNode Merge(ListNode list1,ListNode list2) {
ListNode res = new ListNode(0);
ListNode a = new ListNode(0);
a.next = res;
while(list1 !=null || list2 !=null){
if(list1 ==null && list2 !=null){
res.next = list2;
list2 = null;
}else if(list1 !=null && list2 ==null){
res.next = list1;
list1 = null;
}else{
if(list1.val<list2.val){
ListNode C = new ListNode(list1.val);
res.next = C;
res = res.next;
list1 = list1.next;
}else{
ListNode C = new ListNode(list2.val);
res.next = C;
res = res.next;
list2 = list2.next;
}
}
}
return res.next.next;
}
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;
}
}
public ArrayList<Integer> printMatrix(int [][] matrix) {
int a = matrix.length;
int b = matrix[0].length;
ArrayList res = new ArrayList();
int start = 0,end = a-1;
int flag = 0;
if(a == 1){
for(int j=0;j<b;j++){
res.add(matrix[0][j]);
}
return res;
}
if(b == 1){
for(int i=0;i<a;i++){
res.add(matrix[i][0]);
}
return res;
}
while(start!=end){
if(end-start==1){
for(int j =flag;j<=b-1-flag;j++){
res.add(matrix[start][j]);
}
for(int j =b-1-flag;j>=flag;j--){
res.add(matrix[end][j]);
}
return res;
}
for(int j =flag;j<=b-1-flag;j++){
res.add(matrix[start][j]);
}
for(int i=start+1;i<end;i++){
res.add(matrix[i][b-1-flag]);
}
for(int j =b-1-flag;j>=flag;j--){
res.add(matrix[end][j]);
}
for(int i=end-1;i>start;i--){
res.add(matrix[i][flag]);
}
if(end-start==2){
for(int j=flag+1;j<b-1-flag;j++){
res.add(matrix[end-1][j]);
}
return res;
}
if(b-1-flag ==flag+1){
return res;
}
if(b-1-flag ==flag+2){
for(int i =start+1;i<=end-1;i++){
res.add(matrix[i][flag+1]);
}
return res;
}
start++;
end--;
flag++;
}
return res;
}
题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
-思路:任务完成栈的数据结构同时要加一个min函数,完成出栈、入栈、获取栈顶元素。
规定了时间复杂度,肯定要牺牲空间。加入min辅助栈,出栈的时候两个都出;入栈的时候,min栈需要比较大小;最小值总是在min的top
static Stack<Integer> data = new Stack<Integer>();
static Stack<Integer> min = new Stack<Integer>();
public static void push(int node) {
data.push(node);
if(min.isEmpty() || node<min.peek()){
min.push(node);
}else{
min.push(min.peek());
}
}
public static void pop() {
min.pop();
data.pop();
}
public static int top() {
return data.peek();
}
public static int min() {
return min.peek();
}
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
public boolean IsPopOrder(int [] pushA,int [] popA) {
int len = pushA.length;
Stack<Integer> data = new Stack<Integer>();
int i=0,j=0;
while(j<len){
if (i<len && pushA[i] == popA[j]) {
i++;
j++;
}else if (data.isEmpty()){//入栈不等于出栈
data.push(pushA[i]);
i++;
}else if(data.peek() == popA[j]){
data.pop();
j++;
}else if(i >= len-1){
return false;
}else{
data.push(pushA[i]);
i++;
}
}
return true;
}
public static boolean IsPopOrder1(int [] pushA,int [] popA){
int len = pushA.length;
Stack<Integer> data = new Stack<Integer>();
for(int i=0,j=0;i<len;i++){
data.push(pushA[i]);
while(!data.isEmpty() && data.peek() == popA[j]){
data.pop();
j++;
}
}
return data.isEmpty();
}
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
public RandomListNode Clone(RandomListNode pHead)
{
if(pHead == null){
return null;
}
RandomListNode res = pHead;
while(res != null){
RandomListNode clone = new RandomListNode(res.label);
clone.next = res.next;
res.next = clone;
res = res.next.next;
}
res = pHead;
while(res!=null){
res.next.random = res.random == null? null:res.random.next;
res = res.next.next;
}
res = pHead;
RandomListNode c = pHead.next;
//就是把遍历每个,同时将他的next变为next.next
while(res.next != null){
RandomListNode cloneNode = res.next;
res.next = res.next.next;
res = cloneNode;
}
return c;
}
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
return sort(pre,in,0,0,pre.length);
}
private static TreeNode sort(int[] pre,int[] in,int i,int j,int count){
if(count>0){
int a=0;
for(;a<count;a++){
if(pre[i] == in[a+j])
break;
}
TreeNode root = new TreeNode(pre[i]);
root.left = sort(pre,in,i+1,j,a);
root.right = sort(pre,in,i+a+1,j+a+1,count-a-1);
return root;
}
return null;
}
}
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
boolean result = false;
if(root1 != null &&root2 != null){
if(root1.val == root2.val){
result = isSubtree(root1,root2);
}
if(!result){
result = HasSubtree(root1.left,root2);
}
if(!result){
result = HasSubtree(root1.right,root2);
}
}
return result;
}
public boolean isSubtree(TreeNode root1,TreeNode root2){
if(root2 == null){
return true;
}
if(root1 == null){
return false;
}
if(root1.val!=root2.val){
return false;
}
return isSubtree(root1.left,root2.left) && isSubtree(root1.right,root2.right);
}
操作给定的二叉树,将其变换为源二叉树的镜像。
public static void Mirror(TreeNode root) {
TreeNode temp = null;
if(root!=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);
}
}
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
ArrayList<Integer> res = new ArrayList<Integer>();
ArrayList<TreeNode> queue = new ArrayList<TreeNode>();
if(root == null){
return res;
}
queue.add(root);
while(!queue.isEmpty()){
TreeNode temp = queue.remove(0);
if(temp.left!=null)
queue.add(temp.left);
if(temp.right!=null)
queue.add(temp.right);
res.add(temp.val);
}
return res;
}
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
❌错误仅仅考虑了根节点与左右子树关系,没有考虑左右子树是否是二叉查找树
public boolean VerifySquenceOfBST(int [] sequence) {
int len = sequence.length;
if(len<1){
return true;
}
int G = sequence[len-1],i=0;
for(;i<len-1;i++){
if(sequence[i]>G){
break;
}
}
int j =i;
for(;j<len-1;j++){
if(sequence[j]<G){
break;
}
}
if(j == len-1){
return true;
}else{
return false;
}
}
正确✔(使用递归)
public boolean VerifySquenceOfBST(int [] sequence) {
int len = sequence.length;
if(len<1){
return false;
}
return BST(sequence,0,len-1);
}
public boolean BST(int [] sequence,int x,int y){
if(y-x>1){
int i=x,j;
for(;i<y;i++){
if(sequence[i]>sequence[y]){
break;
}
}
j=i;
for(;j<y;j++){
if(sequence[j]<sequence[y]){
return false;
}
}
return BST(sequence,x,i-1) && BST(sequence,i,j-1);
}
return true;
}
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
ArrayList<Integer> R = new ArrayList<Integer>();
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int target) {
if(root == null){
return res;
}
find(root,target);
return res;
}
public void find(TreeNode root, int target){
R.add(root.val);
if(root.val == target && root.left == null && root.right == null){
res.add(new ArrayList<>(R));
}
if(root.left!=null){
find(root.left,target-root.val);
}
if(root.right!=null){
find(root.right,target-root.val);
}
R.remove(R.size()-1);
}
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
public TreeNode Convert(TreeNode root){
TreeNode first = null;
if(root!=null){
Stack<TreeNode> temp = new Stack<TreeNode>();
TreeNode pre = null;
boolean flag = true;
while(!temp.isEmpty() || root!=null){
if(root!=null){
temp.push(root);
root = root.left;
}else{
root = temp.pop();
if(flag){
first = root;
pre = root;
flag = false;
}else{
pre.right = root;
root.left = pre;
pre = root;
}
root = root.right;
}
}
}
return first;
}
TreeNode head = null;
TreeNode first = null;
public TreeNode Convert1(TreeNode root){
sub(root);
return first;
}
public void sub(TreeNode root){
if(root == null) return;
sub(root.left);
if(head == null){
first = root;
head = root;
}else{
root.left = head;
head.right = root;
head = root;
}
sub(root.right);
}
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
public static int MoreThanHalfNum_Solution(int[] array) {
int temp,len = array.length,start=0,end =len-1;
temp = getmid(array,start,end);
while (temp!=len/2){
if(temp>len/2){
end = temp-1;
temp = getmid(array,start,end);
}else{
start = temp+1;
temp = getmid(array,temp+1,end);
}
}
if(check(array,array[temp]))
return array[temp];
else
return 0;
}
//
public static boolean check(int [] array,int num){
int len = array.length,time=0;
for(int i=0;i<len;i++){
if(num == array[i])
time++;
}
if(time>len/2)
return true;
else
return false;
}
public static int getmid(int [] num,int i,int j){
int temp = num[i];
while(i<j){
while (i<j && temp<=num[j]){
j--;
}
if(i<j){
num[i] = num[j];
}
while (i<j && temp >= num[i]){
i++;
}
if(i<j){
num[j] = num[i];
}
}
num[i] = temp;
return i;
}
//方法2
public static int MoreThanHalfNum_Solution1(int[] array) {
int len = array.length;
int temp=array[0],count=1,i,j;
for(i=1;i<len;i++){
if(array[i-1] == array[i]){
count++;
temp = array[i];
}else if(count == 1){
temp = array[i];
}else{
count--;
}
}
if(check(array,temp))
return temp;
else
return 0;
}
//
public static boolean check(int [] array,int num){
int len = array.length,time=0;
for(int i=0;i<len;i++){
if(num == array[i])
time++;
}
if(time>len/2)
return true;
else
return false;
}
//取出数组中不连续的值,达到1/3len个(排序之后)
public static ArrayList san(int [] a){
int len = a.length;
ArrayList list = new ArrayList();
int x=0,y=0;
int xnum=0,ynum=0;
for(int i =0;i<len;i++){
if(xnum == 0||x==a[i]){
x = a[i];
++xnum;
}else if(ynum == 0||y==a[i]){
y = a[i];
++ynum;
}else{
xnum--;
ynum--;
}
}
if(check(x,a)){
list.add(x);
}
if(check(y,a)){
list.add(y);
}
return list;
}
public static boolean check(int x,int[] a) {
int num =0;
for(int i=0;i<a.length;i++){
if(a[i] == x){
num++;
}
}
if(num>a.length/3)
return true;
else
return false;
}
//连续的更简单,就是遍历一次只用一个变量即可
public static ArrayList san1(int [] a){
int len = a.length;
ArrayList list = new ArrayList();
int x=0;
int xnum=0;
for(int i =0;i<len;i++){
if(xnum == 0||x==a[i]){
x = a[i];
++xnum;
}else{
if(xnum>len/3){
list.add(x);
xnum=1;
x=a[i];
}else{
xnum=1;
x=a[i];
}
}
}
return list;
}
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
int len = input.length;
int start =0,end = len-1;
int temp = getmid(input,start,end);
ArrayList<Integer> res = new ArrayList<Integer>();
if(len<k || k<=0 || len<=0){
return res;
}
while(temp!=k-1){
if(temp>k-1){
end = temp-1;
temp = getmid(input,start,end);
}else{
start = temp+1;
temp = getmid(input,start,end);
}
}
for(int i=0;i<=temp;i++){
res.add(input[i]);
}
return res;
}
//核心算法,也是快排的重要
public int getmid(int [] array,int i,int j){
int temp = array[i];
while(i<j){
if(i<j && temp<=array[j]){
j--;
}
if(i<j){
array[i] = array[j];
}
if(i<j&&temp>=array[i]){
i++;
}
if(i<j){
array[j] = array[i];
}
}
array[i] = temp;
return i;
}
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> res = new ArrayList<Integer>();
int len = input.length;
if(k<1||len<k){
return res;
}
int [] copy = new int[k];
for(int i=0;i<k;i++){
copy[i] = input[i];
}
for(int x=k/2-1;x>=0;x--){
sift(copy,x,k);
}
for(int i=k;i<input.length;i++){
if(copy[0]>input[i]){
copy[0] = input[i];
sift(copy,0,k);
}
}
for(int i=0;i<k;i++){
res.add(copy[i]);
}
return res;
}
//构成最大堆
public static void sift (int[] input,int low,int high){
int parent = low;
int temp = input[parent];
int child = 2*parent+1;
while(child<high){
if(child<high-1 && input[child]<input[child+1]){
child++;
}
if(temp<input[child]){
input[parent] = input[child];
parent = child;
child = 2*parent+1;
}else{
break;
}
}
input[parent] = temp;
}
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
public static ArrayList<String> Permutation(String str) {
char [] s = str.toCharArray();
ArrayList<String> ret = new ArrayList<String>();
if(s.length>0 && str!=null)
fullsort(s,0,ret);
Collections.sort(ret);
return ret;
}
public static void fullsort(char[] s,int begin,ArrayList<String> ret){
if(begin == s.length-1){
ret.add(String.valueOf(s));
}else{
Set<Character> chasrset = new HashSet<Character>();
for(int i = begin;i<s.length;i++){
if(i==begin || !chasrset.contains(s[i])){
chasrset.add(s[i]);
swap(s,i,begin);
fullsort(s,begin+1,ret);
swap(s,begin,i);
}
}
}
}
public static void swap(char [] s,int i,int j){
char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
一般而言,设P是[1,n]的一个全排列。
P=P1P2…Pn=P1P2…Pj-1PjPj+1…Pk-1PkPk+1…Pn
find: j=max{i|Pik=max{i|Pi>Pj}
1, 对换Pj,Pk,
2, 将Pj+1…Pk-1PjPk+1…Pn翻转
P’= P1P2…Pj-1PkPn…Pk+1PjPk-1…Pj+1即P的下一个
public ArrayList<String> Permutation2(String str){
ArrayList<String> list = new ArrayList<String>();
if(str==null || str.length() == 0){
return list;
}
char [] temp = str.toCharArray();
Arrays.sort(temp);
list.add(String.valueOf(temp));
int len = temp.length;
while(true){
int lIndex = len-1;
int rIndex = 0;
while(lIndex>=1&& temp[lIndex-1]>=temp[lIndex]){
lIndex--;
}
if(lIndex == 0)
break;
rIndex = lIndex;
while(rIndex<len && temp[rIndex]>temp[rIndex-1])
rIndex++;
swap(temp,lIndex-1,rIndex-1);
reverse(temp,lIndex);
list.add(String.valueOf(temp));
}
return list;
}
private void reverse(char[] chars,int k){
if(chars == null || chars.length<=k){
return;
}
int len = chars.length;
for(int i =0;i<(len-k)/2;i++){
int m = k+i;
int n = len-1-i;
if(m<=n){
swap(chars,m,n);
}
}
}
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
public int FindGreatestSumOfSubArray(int[] array) {
int max=array[0],len=array.length,ret=array[0];
if(len == 0 || array == null)
return 0;
for(int i=1;i<len;i++){
if(max>=0){
max += array[i];
}else{
max = array[i];
}
if(max>ret){
ret = max;
}
}
return ret;
}
public int FindGreatestSumOfSubArray1(int[] array) {
int max=array[0],len=array.length,ret=array[0];
if(len == 0 || array == null)
return 0;
for(int i=1;i<len;i++){
max = Math.max(max+array[i],array[i]);
ret = Math.max(ret,max);
}
return ret;
}