Single Number
Given 2*n + 1
numbers,
every numbers occurs twice except one, find it.
[1,2,2,1,3,4,3]
, return 4
public class Solution {
/**
*@param A : an integer array
*return : a integer
*/
public int singleNumber(int[] A) { //不符合題目要求空間複雜度
Map<Integer,Integer> map=new HashMap<>();
for(int i=0;i<A.length;i++){
if(!map.containsKey(A[i])){
map.put(A[i],1);
}else{
map.put(A[i],map.get(A[i])+1);
}
}
int result=0;
for(Integer i:map.keySet()){
if(map.get(i)==1){
result=i;
}
}
return result;
}
}
思路:異或運算public class Solution {
/**
*@param A : an integer array
*return : a integer
*/
public int singleNumber(int[] A) {
if(A==null || A.length==0){
return 0;
}
int result=0;
for(int i=0;i<A.length;i++){
result^=A[i];
}
return result;
}
}
Single Number II
Given 3*n + 1
numbers,
every numbers occurs triple times except one, find it.
[1,1,2,3,3,3,2,2,4,1]
return 4
思路:利用位運算來消除重複三次的數
public class Solution {
/**
* @param A : An integer array
* @return : An integer
*/
public int singleNumberII(int[] A) {
int[] bits=new int[32];
for(int i=0;i<A.length;i++){
for(int j=0;j<32;j++){
int move;
if((move=A[i]>>j)==0){ //右移:二進制表示除以2
break;
}
bits[j]+=move & 1; //按位與:只有兩位同時爲1,結果才爲1
}
}
int target=0;
for(int i=0; i<32; i++){
target+=(bits[i]%3 <<i);
}
return target;
}
}
Majority Number
Given an array of integers, the majority number is the number that occurs more
than half
of the size of the array. Find it.
You may assume that the array is non-empty and the majority number always exist in the array.
[1, 1, 1, 1, 2, 2, 2]
, return 1
從i=1,第二個數開始遍歷list,
如果遍歷到的數等於major,count++
如果遍歷到的數不等於major,如果此時的count>0,還有可以抵消的數,就count--,否則就重置major
想法:因爲major出現的次數多餘一半,因此當真正的major被置爲major的時候,它的個數一定可以被所有其他的數用來抵消,最後還有剩餘,返回即可
public class Solution {
/**
* @param nums: a list of integers
* @return: find a majority number
*/
public int majorityNumber(ArrayList<Integer> nums) {
int major=nums.get(0);
int count=1;
for(int i=1;i<nums.size();i++){
if(nums.get(i)==major){
count++;
}else{
if(count>0){
count--;
}else{
major=nums.get(i);
}
}
}
return major;
}
}
Majority Number II
Given an array of integers, the majority number is the number that occurs more
than 1/3
of the size of the array.
Find it.
There is only one majority number in the array.
[1, 2, 1, 2, 1, 3, 3]
, return 1
.public class Solution {
/**
* @param nums: A list of integers
* @return: The majority number that occurs more than 1/3
*/
public int majorityNumber(ArrayList<Integer> nums) {
if(nums==null || nums.size()==0){
return -1;
}
int candidate1=0;
int candidate2=0;
int count1=0;
int count2=0;
for(int i=0;i<nums.size();i++){
if(nums.get(i)==candidate1){
count1++;
}else if(nums.get(i)==candidate2){
count2++;
}else if(count1==0){
candidate1=nums.get(i);
count1=1;
}else if(count2==0){
candidate2=nums.get(i);
count2=1;
}else{
count1--;
count2--;
}
}
count1=count2=0;
for(int i=0;i<nums.size();i++){
if(nums.get(i)==candidate1){
count1++;
}else if(nums.get(i)==candidate2){
count2++;
}
}
return count1>count2?candidate1:candidate2;
}
}
Gas Station
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]
.
You have a car with an unlimited gas tank and it costs cost[i]
of
gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.
Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.
The solution is guaranteed to be unique.
Given 4
gas
stations with gas[i]=[1,1,3,1]
, and the cost[i]=[2,2,1,1]
.
The starting gas station's index is 2
.
Challenge : O(n) time and O(1) extra space
思路:從頭開始遍歷,(每個加油站能加到的油) - (這個加油站到下一個加油站消耗的油),就是當前剩餘記爲temp
如果當前剩餘temp<0,說明不能從這個站開始走,要嘗試從下一個站開始走,此時temp又要重置爲0
如果可以走,一直遍歷到最後
如果(總加到的油量) - (總消耗的油量),也就是sum<0,說明走不到底,返回-1,否則就返回嘗試開始走的index
public class Solution {
/**
* @param gas: an array of integers
* @param cost: an array of integers
* @return: an integer
*/
public int canCompleteCircuit(int[] gas, int[] cost) {
if(gas==null || cost==null || gas.length==0 || cost.length==0){
return -1;
}
int temp=0;
int sum=0;
int index=0;
for(int i=0;i<gas.length;i++){
temp+=gas[i]-cost[i];
sum+=gas[i]-cost[i]; //從開始遍歷的時候就計數
if(temp<0){
index=i+1;
temp=0;
}
}
return sum<0?-1:index;
}
}
Largest Number
Given a list of non negative integers, arrange them such that they form the largest number.
The result may be very large, so you need to return a string instead of an integer.
Given [1, 20,
23, 4, 8]
, the largest formed number is 8423201
.
Challenge : Do it in O(nlogn) time complexity.
思路:先將整形數組轉換爲字符串數組
然後調用myComparator比較器使字符串按照相加結果的從大到小排序,例如[34,30,9]->[9,34,30]
再依次取出每一個字符串數組的元素拼接好即可。
但是要注意一些情況,比如[0,0],輸出要是"0",而不是"00",因此,只要排序好的數組的第一個元素的第一位是'0',結果就是一定是”0“
public class Solution {
/**
*@param num: A list of non negative integers
*@return: A string
*/
public String largestNumber(int[] num) {
if(num==null || num.length==0){
return "";
}
String[] temp=new String[num.length];
for(int i=0;i<num.length;i++){
temp[i]=String.valueOf(num[i]);
}
Arrays.sort(temp,myComparator);
String result="";
if(temp[0].charAt(0)=='0'){
return "0";
}
for(int i=0;i<temp.length;i++){
result+=temp[i];
}
return new StringBuffer(result).toString();
}
private Comparator<String> myComparator=new Comparator<String>(){ //我這裏按從大到小排序,也可以從小到大
public int compare(String a,String b){
return (b+a).compareTo(a+b);
}
};
}
Next Permutation
Given a list of integers, which denote a permutation.
Find the next permutation in ascending order.
The list may contains duplicate integers.
For [1,3,2,3]
, the next
permutation is [1,3,3,2]
For [4,3,2,1]
, the next
permutation is [1,2,3,4]
public class Solution {
/**
* @param nums: A list of integers
* @return: A list of integers that's next permuation
*/
public int[] nextPermutation(int[] nums) {
if(nums.length <= 1){
return nums;
}
int i=nums.length-2;
while(i>=0 && nums[i]>=nums[i+1]){ //找到第一個下降點,還要注意等於的情況也要跳過
i--;
}
if(i>=0){ //從右向左找到第一個比下降點大,卻儘可能小的數
int j=nums.length-1;
while(j>i && nums[j]<=nums[i]){
j--;
}
swap(nums, i, j); //交換兩個數
}
reverse(nums, i+1, nums.length-1); //下降點後面遍歷過的序列reverse成升序列
return nums; //如果本來就是最大序列,像4321,while循環的時候i會i減小到-1
} //然後就是整個序列reverse
private void swap(int[] nums,int i,int j){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
private void reverse(int[] nums,int left,int right){
while(left<right){
swap(nums,left++,right--);
}
}
}
Delete Digits
Given string A representative a positive integer which has N digits, remove any k digits of the number, the remaining digits are arranged according to the original order to become a new positive integer.
Find the smallest integer after remove k digits.
N <= 240 and k <= N
Given an integer A = "178542"
,
k = 4
return a string "12"
public class Solution {
/**
*@param A: A positive integer which has N digits, A is a string.
*@param k: Remove k digits.
*@return: A string
*/
public String DeleteDigits(String A, int k) {
StringBuffer sb = new StringBuffer(A);
int i,j;
for (i=0;i<k;i++) {
for (j=0; j<sb.length()-1 && sb.charAt(j)<=sb.charAt(j+1); j++) {}
sb.delete(j, j+1);
}
while (sb.length()>1 && sb.charAt(0)=='0') { //刪完如果有前導零,去掉
sb.delete(0, 1);
}
return sb.toString();
}
}
jump Games
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
This problem have two method which is Greedy
and Dynamic
Programming
.
The time complexity of Greedy
method is O(n)
.
The time complexity of Dynamic
Programming method is O(n^2)
.
We manually set the small data set to allow you pass the test in both ways. This is just to let you learn how to use this problem in dynamic programming ways. If you finish it in dynamic programming ways, you can try greedy method to make it accept again.
A = [2,3,1,1,4]
, return true
.
A = [3,2,1,0,4]
, return false
.
public class Solution {
/**
* @param A: A list of integers
* @return: The boolean answer
*/
public boolean canJump(int[] A) {
int reach=A[0];
for(int i=1;i<A.length;i++){
if(reach>=i && A[i]+i>=reach){
reach=A[i]+i;
}
}
return reach>=A.length-1;
}
}