题链
题解:双指针问题,设两个指针l,r分别指向数组首尾,然后每次判断nums[l]+nums[r]是否大于target,如果大于则r–,r遍历完后l++.
public int[] twoSum(int[] nums, int target) {
int l = 0,r = nums.length-1;
while(l < r){
while(nums[l] + nums[r] > target){
r--;
}
if(nums[l] + nums[r] == target){
return new int[]{nums[l],nums[r]};
}
l++;
}
return new int[2];
}
题链
题解:双指针问题.设两个指针l,r每次记录sum=(l+r)(r-l+1)/2与target的大小,当sum==target则返回l~r,sum< target则r++,否则l++.
public int[][] findContinuousSequence(int target) {
List<int[]> list = new ArrayList<>();
for(int l = 1,r = 2; l < r;){
int sum = (l + r) * (r - l + 1) / 2;
if(sum == target){
int[] cur = new int[r - l + 1];
for(int i = l;i <= r; i++){
cur[i-l] = i;
}
list.add(cur);
l++;
}else if(sum < target){
r++;
}else{
l++;
}
}
return list.toArray(new int[list.size()][]);
}
题链
题解:首先去掉原字符串的前后的多余空格,然后分别翻转每个单词,然后再翻转整个字符串.
public String reverseWords(String s) {
if(s == null || s.length() == 0){
return s;
}
String[] strs = s.split(" ");
String ans = "";
int n = strs.length;
for(int i = n-1; i >= 0; i--){
if("".equals(strs[i])){
continue;
}
ans += strs[i] + " ";
}
if(ans.length() == 0){
return ans;
}
return ans.substring(0,ans.length()-1);
}
public char[] reverse(char[] arr,int l,int r){
while(l < r){
char tmp = arr[l];
arr[l] = arr[r];
arr[r] = tmp;
l++;
r--;
}
return arr;
}
题链
题解:与翻转字符串思路类似,以第k个字符作为分割分别翻转左侧和右侧的子字符串后再翻转整个字符串.还有一种骚操作:将两个字符串拼接起来,然后返回新字符串的第k位到第k+length位.
public String reverseLeftWords(String s, int n) {
String ans = s + s;
int len = s.length();
return ans.substring(n,n+len);
}
题链
题解:考察的是单调队列的应用.维护一个单调队列:队首为最大值.每次更新新元素时要保证队列的递减.同时在移除头部元素时要检验队首元素的下标是否应该被移除.
public int[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> q = new LinkedList<>();
int n = nums.length;
if(n == 0){
return nums;
}
int[] ans = new int[n - k + 1];
int index = 0;
for(int i = 0; i < n; i++){
while(!q.isEmpty() && nums[i] >= nums[q.peekLast()]){
q.pollLast();
}
q.offerLast(i);
if(i >= k - 1){
ans[index++] = nums[q.peekFirst()];
if(q.peekFirst() == i - k + 1){
q.pollFirst();
}
}
}
return ans;
}
题链
题解:维护两个队列,一个队列负责元素的进和出,一个队列负责表示当前队列中的最大元素.分别记为q和maxQ,在进元素时,q中直接进元素,maxQ进行一次判断:当maxQ为空或maxQ的队头元素小于等于进入元素时将元素放入队列中,否则先弹出maxQ的队头元素.在出元素时,q中直接出元素,maxQ中要判断出的元素是否等于maxQ的队头元素,如果等于将maxQ的队头元素也弹出.
Deque<Integer> q;
Deque<Integer> maxQ;
public MaxQueue() {
q = new LinkedList<>();
maxQ = new LinkedList<>();
}
public int max_value() {
if(q.size() == 0){
return -1;
}
return maxQ.peekFirst();
}
public void push_back(int value) {
q.offerLast(value);
while(!maxQ.isEmpty() && value > maxQ.peekLast()){
maxQ.pollLast();
}
maxQ.offerLast(value);
}
public int pop_front() {
if(q.size() == 0){
return -1;
}
if(maxQ.peekFirst().equals(q.peekFirst())){
maxQ.pollFirst();
}
return q.pollFirst();
}
题链
题解:动态规划.记录f[i][j]为i个骰子向上和为j时的概率.那么f[i][j] = (f[i-1][j-1]+…+f[i-1][j-6])/6.
public double[] dicesProbability(int n) {
double[] dp = new double[6];
Arrays.fill(dp,1.0/6);
for(int i = 2; i <= n; i++){
double[] cur = new double[5*i+1];
for(int j = 0; j < dp.length; j++){
//之所以正着推是为了避免多次讨论数组越界
for(int k = 0; k < 6; k++){
cur[j+k] += dp[j] / 6.0;
}
}
dp = cur;
}
return dp;
}
题链
题解:简单的模拟题.首先对数组排序,当数组中出现两个相同非0的数字时返回false.记录0出现的次数cnt和数组中非零的最大差sum-1-(3-cnt,比较两者的值,当前者大于等于后者时返回true.
public boolean isStraight(int[] nums) {
Arrays.sort(nums);
for(int i = 0; i < 4; i++){
if(nums[i] == nums[i+1] && nums[i] != 0){
return false;
}
}
if(isV(nums)){
return true;
}
int cnt = 0;
for(int i = 0; i < 5; i++){
if(nums[i] == 0){
cnt++;
}
}
int sum = 0;
sum = nums[4] - nums[cnt] -1-(3-cnt);
return sum <= cnt;
}
public boolean isV(int[] nums){
return (nums[0] + 1 == nums[1] && nums[1] + 1 == nums[2]
&& nums[2] + 1 == nums[3] && nums[3] + 1 == nums[4]);
}
题链
题解:约瑟夫环.对于n个元素,第一个要删除的数是第m%n个,假设n-1个元素最终剩下的元素的编号是x,那么f[n] = (m%n+x) % n,因此可以通过迭代得到最终结果.
public int lastRemaining(int n, int m) {
int a = 0;
for(int i = 2; i <= n; i++){
a = (m+a)%i;
}
return a;
}
题链
题解:利用贪心去解决.首先定义一个当前天的最小价格minPrice和当前天得到的最大利润maxProfit.顺序遍历数组的每个元素,每次比较minPrice与当前元素的值,如果前者大于后者则用后者更细前者,否则判断当前天数-minPrince与maxProfit的大小,如果前者更大,则用前者更新后者.
public int maxProfit(int[] prices) {
int price = Integer.MAX_VALUE;
int profit = 0;
int len = prices.length;
for(int i = 0; i < len; i++){
if(prices[i] < price){
price = prices[i];
}else if(prices[i] - price > profit){
profit = prices[i] - price;
}
}
return profit;
}