CD149 转圈打印矩阵
public class CD149_1
{
public static void solution(int[][] arr)
{
int up = 0, down = arr.length - 1, left = 0, right = arr[0].length - 1;
while (up <= down && left <= right)
{
for (int i = left; i <= right; i++)
System.out.print(arr[up][i] + " ");
for (int i = up + 1; i < down; i++)
System.out.print(arr[i][right] + " ");
for (int i = right; up != down && i >= left; i--)
System.out.print(arr[down][i] + " ");
for (int i = down - 1; left != right && i > up; i--)
System.out.print(arr[i][left] + " ");
up++;
down--;
left++;
right--;
}
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int m, n;
m = in.nextInt();
n = in.nextInt();
int[][] arr = new int[m][n];
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
arr[i][j] = in.nextInt();
solution(arr);
}
}
CD150 将正方形矩阵顺时针转动 90°
public class CD150_1
{
public static void solution(int[][] arr)
{
int n = arr.length;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (i < j) break;
int temp = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = temp;
}
}
for (int i = 0; i < n; i++)
{
int l = 0, r = n - 1;
while (l <= r)
{
int temp = arr[i][l];
arr[i][l] = arr[i][r];
arr[i][r] = temp;
l++;
r--;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
System.out.print(arr[i][j] + (j == n - 1 ? "" : " "));
System.out.println();
}
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n;
n = in.nextInt();
int[][] arr = new int[n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
arr[i][j] = in.nextInt();
solution(arr);
}
}
CD151 “之”字形打印矩阵
public class CD151_1
{
public static void solution(int[][] arr)
{
int x = 0, y = 0, m = arr.length - 1, n = arr[0].length - 1;
boolean up = true;
while (x != m || y != n)
{
if (up)
{
while (x >= 0 && y <= n)
System.out.print(arr[x--][y++] + " ");
if (y == n + 1)
{
x += 2;
y = n;
}
else if (x == -1) x = 0;
}
else
{
while (x <= m && y >= 0)
System.out.print(arr[x++][y--] + " ");
if (x == m + 1)
{
x = m;
y += 2;
}
else if (y == -1)
y = 0;
}
up = !up;
}
System.out.println(arr[m][n]);
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int m, n;
m = in.nextInt();
n = in.nextInt();
int[][] arr = new int[m][n];
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
arr[i][j] = in.nextInt();
solution(arr);
}
}
CD152 找到无序数组中最小的 k 个数 ⭐
/* 堆 */
public class CD152_1
{
public static void solution(int[] arr, int k)
{
int len = arr.length - 1;
for (int i = (len - 1) / 2; i >= 0; i--)
adjustHeap(arr, i, len);
while (k-- > 0)
{
System.out.print(arr[0] + " ");
arr[0] = arr[len--];
adjustHeap(arr, 0, len);
}
}
public static void adjustHeap(int[] arr, int idx, int len)
{
int cur;
while (2 * idx + 1 <= len)
{
cur = 2 * idx + 1;
if (2 * idx + 2 <= len && arr[2 * idx + 1] > arr[2 * idx + 2])
cur++;
if (arr[idx] > arr[cur])
{
int temp = arr[idx];
arr[idx] = arr[cur];
arr[cur] = temp;
}
else break;
idx = cur;
}
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, k;
n = in.nextInt();
k = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
solution(arr, k);
}
}
/* ⭐BFPRT算法⭐ */
public class CD152_2
{
public static int[] solution(int[] arr, int k)
{
if (k < 1 || k > arr.length) return arr;
int minKth = getMinKthByBFPRT(arr, k);
int[] res = new int[k];
int index = 0;
for (int i = 0; i != arr.length; i++)
if (arr[i] < minKth)
res[index++] = arr[i];
for (; index != res.length; index++)
res[index] = minKth;
return res;
}
public static int getMinKthByBFPRT(int[] arr, int K)
{
int[] copyArr = new int[arr.length];
System.arraycopy(arr, 0, copyArr, 0, arr.length);
return select(copyArr, 0, copyArr.length - 1, K - 1);
}
public static int select(int[] arr, int begin, int end, int i)
{
if (begin == end) return arr[begin];
int pivot = medianOfMedians(arr, begin, end);
int[] pivotRange = partition(arr, begin, end, pivot);
if (i >= pivotRange[0] && i <= pivotRange[1])
return arr[i];
else if (i < pivotRange[0])
return select(arr, begin, pivotRange[0] - 1, i);
else
return select(arr, pivotRange[1] + 1, end, i);
}
public static int medianOfMedians(int[] arr, int begin, int end)
{
int num = end - begin + 1;
int offset = num % 5 == 0 ? 0 : 1;
int[] mArr = new int[num / 5 + offset];
for (int i = 0; i < mArr.length; i++)
{
int beginI = begin + i * 5;
int endI = beginI + 4;
mArr[i] = getMedian(arr, beginI, Math.min(end, endI));
}
return select(mArr, 0, mArr.length - 1, mArr.length / 2);
}
public static int[] partition(int[] arr, int begin, int end, int pivotValue)
{
int small = begin - 1;
int cur = begin;
int big = end + 1;
while (cur != big)
{
if (arr[cur] < pivotValue)
swap(arr, ++small, cur++);
else if (arr[cur] > pivotValue)
swap(arr, cur, --big);
else
cur++;
}
int[] range = new int[2];
range[0] = small + 1;
range[1] = big - 1;
return range;
}
public static int getMedian(int[] arr, int begin, int end)
{
insertionSort(arr, begin, end);
int sum = end + begin;
int mid = (sum / 2) + (sum % 2);
return arr[mid];
}
public static void insertionSort(int[] arr, int begin, int end)
{
for (int i = begin + 1; i != end + 1; i++)
{
for (int j = i; j != begin; j--)
{
if (arr[j - 1] > arr[j])
swap(arr, j - 1, j);
else
break;
}
}
}
public static void swap(int[] arr, int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, k;
n = in.nextInt();
k = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
int[] res = solution(arr, k);
System.out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}
}
CD153 需要排序的最短子数组长度⭐
/*⭐⭐*/
public class CD153_1
{
public static int solution(int[] arr)
{
int maxIdx = -1, minIdx = -1, mmax, mmin;
mmax = arr[0];
for (int i = 1; i < arr.length; i++)
{
if (arr[i] < mmax)
maxIdx = i;
else
mmax = arr[i];
}
if (maxIdx == -1) return 0;
mmin = arr[arr.length - 1];
for (int i = arr.length - 2; i >= 0; i--)
{
if (arr[i] > mmin)
minIdx = i;
else
mmin = arr[i];
}
return maxIdx - minIdx + 1;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n;
n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
System.out.println(solution(arr));
}
}
CD154 在数组中找到出现次数大于一半的数
/* 摩尔投票 */
public class CD154_1
{
public static int solution(int[] arr)
{
int cnt = 0, ans = -1;
for (int num : arr)
{
if (cnt == 0 || ans == num)
{
ans = num;
cnt++;
}
else
cnt--;
}
cnt = 0;
for (int num : arr)
if (num == ans)
cnt++;
if (cnt > arr.length / 2) return ans;
else return -1;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n;
n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
System.out.println(solution(arr));
}
}
CD155 在数组中找到出现次数大于 N/K 的数⭐
/* ⭐摩尔投票⭐ */
public class CD155_1
{
public static void solution(int[] arr, int k)
{
HashMap<Integer, Integer> cands = new HashMap<>();
HashMap<Integer, Integer> cnt = new HashMap<>();
boolean flag;
for (int num : arr)
{
if (cands.containsKey(num))
cands.put(num, cands.get(num) + 1);
else
{
if (cands.size() < k - 1)
cands.put(num, 1);
else
{
ArrayList<Integer> removeList = new ArrayList<>();
Set<Integer> keySet = cands.keySet();
for (int key : keySet)
{
if (cands.get(key) == 1)
removeList.add(key);
else cands.put(key, cands.get(key) - 1);
}
for (int key : removeList)
cands.remove(key);
if (removeList.size() != 0)
cands.put(num, 1);
}
}
}
for (int num : arr)
if (cands.containsKey(num))
cnt.put(num, cnt.getOrDefault(num, 0) + 1);
Set<Integer> keySet = cnt.keySet();
flag = false;
for (int key : keySet)
{
if (cnt.get(key) > arr.length / k)
{
flag = true;
System.out.print(key + " ");
}
}
if (!flag)
System.out.println("-1");
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, k;
n = in.nextInt();
k = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
solution(arr, k);
}
}
CD1 在行列都排好序的矩阵中找指定数
public class CD1_1
{
public static boolean solution(int[][] arr, int k)
{
int row = 0, col = arr[0].length - 1;
while (col >= 0 && row <= arr.length - 1)
{
if (arr[row][col] == k) return true;
else if (arr[row][col] > k) col--;
else row++;
}
return false;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, m, k;
n = in.nextInt();
m = in.nextInt();
k = in.nextInt();
int[][] arr = new int[n][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
arr[i][j] = in.nextInt();
System.out.println(solution(arr, k) ? "Yes" : "No");
}
}
CD2 最长的可整合子数组的长度
public class CD2_1
{
public static int solution(int[] arr)
{
HashSet<Integer> set = new HashSet<>();
int mmax, mmin, ans = 1;
for (int i = 0; i < arr.length; i++)
{
set.clear();
mmax = Integer.MIN_VALUE;
mmin = Integer.MAX_VALUE;
for (int j = i; j < arr.length; j++)
{
if (set.contains(arr[j])) break;
set.add(arr[j]);
mmax = Math.max(mmax, arr[j]);
mmin = Math.min(mmin, arr[j]);
if (mmax - mmin == j - i)
ans = Math.max(ans, j - i + 1);
}
}
return ans;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n;
n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
System.out.println(solution(arr));
}
}
CD3 不重复打印排序数组中相加和为给定值的所有二元组
/* 双指针 */
public class CD3_1
{
public static void solution(int[] arr, int k)
{
int l = 0, r = arr.length - 1;
while (l < r)
{
if (arr[l] + arr[r] == k)
{
if (l == 0 || arr[l] != arr[l - 1])
System.out.println(arr[l] + " " + arr[r]);
l++;
}
else if (arr[l] + arr[r] < k) l++;
else r--;
}
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, k;
n = in.nextInt();
k = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
solution(arr, k);
}
}
CD4 不重复打印排序数组中相加和为给定值的所有三元组
/* 双指针 */
public class CD4_1
{
public static void solution(int[] arr, int k)
{
for (int i = 0; i < arr.length; i++)
if (i == 0 || arr[i] != arr[i - 1])
cal(arr, k - arr[i], i, i + 1);
}
public static void cal(int[] arr, int k, int f, int s)
{
if (s >= arr.length) return;
int l = s, r = arr.length - 1;
while (l < r)
{
if (arr[l] + arr[r] == k)
{
if ((l == 0 || arr[l] != arr[l - 1]) && arr[l] < arr[r])
System.out.println(arr[f] + " " + arr[l] + " " + arr[r]);
l++;
}
else if (arr[l] + arr[r] < k) l++;
else r--;
}
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, k;
n = in.nextInt();
k = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
solution(arr, k);
}
}
CD8 未排序正数数组中累加和为给定值的最长子数组长度
/* 滑动窗口 */
public class CD8_1
{
public static int solution(int[] arr, int k)
{
int l = 0, r = 0, sum = 0, ans = -1;
while (r < arr.length)
{
while (r < arr.length && sum < k)
sum += arr[r++];
if (sum == k)
ans = Math.max(ans, r - l);
sum -= arr[l];
l++;
}
return ans;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, k;
n = in.nextInt();
k = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
System.out.println(solution(arr, k));
}
}
CD9 未排序数组中累加和为给定值的最长子数组长度⭐
/*⭐⭐*/
public class CD9_1
{
public static int solution(int[] arr, int k)
{
int sum = 0, ans = -1;
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
for (int i = 0; i < arr.length; i++)
{
sum += arr[i];
if (map.containsKey(sum - k))
ans = Math.max(ans, i - map.get(sum - k));
if (!map.containsKey(sum))
map.put(sum, i);
}
return ans;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, k;
n = in.nextInt();
k = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
System.out.println(solution(arr, k));
}
}
CD10 未排序数组中累加和为给定值的最长子数组长度(补充1)
public class CD10_1
{
public static int solution(int[] arr)
{
for (int i = 0; i < arr.length; i++)
{
if (arr[i] > 0) arr[i] = 1;
else if (arr[i] < 0) arr[i] = -1;
}
int sum = 0, ans = -1;
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
for (int i = 0; i < arr.length; i++)
{
sum += arr[i];
if (map.containsKey(sum))
ans = Math.max(ans, i - map.get(sum));
else
map.put(sum, i);
}
return ans;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n;
n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
System.out.println(solution(arr));
}
}
CD11 未排序数组中累加和为给定值的最长子数组长度(补充2)
public class CD11_1
{
public static int solution(int[] arr)
{
for (int i = 0; i < arr.length; i++)
if (arr[i] == 0) arr[i] = -1;
int sum = 0, ans = -1;
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
for (int i = 0; i < arr.length; i++)
{
sum += arr[i];
if (map.containsKey(sum))
ans = Math.max(ans, i - map.get(sum));
else
map.put(sum, i);
}
return ans;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n;
n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
System.out.println(solution(arr));
}
}
CD14 未排序数组中累加和小于或等于给定值的最长子数组长度⭐
/*⭐二分⭐*/
public class CD14_1
{
public static int solution(int[] arr, int k)
{
int sum, ans = -1;
int[] h = new int[arr.length];
sum = h[0] = arr[0];
for (int i = 1; i < arr.length; i++)
{
sum += arr[i];
h[i] = Math.max(h[i - 1], sum);
}
sum = 0;
for (int i = 0; i < arr.length; i++)
{
sum += arr[i];
int f = binSearch(h, sum - k);
int len = sum <= k ? i + 1 : i - f;
ans = Math.max(ans, len);
}
return ans;
}
public static int binSearch(int[] h, int num)
{
int l = 0, r = h.length - 1, mid;
while (l <= r)
{
mid = (l + r) / 2;
if (h[mid] < num)
l = mid + 1;
else r = mid - 1;
}
return l;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, k;
n = in.nextInt();
k = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
System.out.println(solution(arr, k));
}
}
/*⭐滑动窗口⭐*/
public class CD14_2
{
public static int solution(int[] arr, int k)
{
int len = arr.length, l = 0, r = 0, sum = 0, ans = -1;
int[] minVal = new int[len];
int[] minEnd = new int[len];
minVal[len - 1] = arr[len - 1];
minEnd[len - 1] = len - 1;
for (int i = len - 2; i >= 0; i--)
{
if (minVal[i + 1] < 0)
{
minVal[i] = arr[i] + minVal[i + 1];
minEnd[i] = minEnd[i + 1];
}
else
{
minVal[i] = arr[i];
minEnd[i] = i;
}
}
for (l = 0; l < len; l++)
{
sum = 0;
r = l;
while (r < arr.length && sum + minVal[r] <= k)
{
sum += minVal[r];
r = minEnd[r] + 1;
}
ans = Math.max(ans, r - l);
}
return ans;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n, k;
n = in.nextInt();
k = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
System.out.println(solution(arr, k));
}
}
CD21 计算数组的小和
/* 归并 */
public class CD21_1
{
public static long solution(int[] arr)
{
return partition(arr, 0, arr.length - 1);
}
public static long partition(int[] arr, int l, int r)
{
if (l >= r) return 0;
int mid = (l + r) / 2;
long left = partition(arr, l, mid);
long right = partition(arr, mid + 1, r);
return left + right + merge(arr, l, mid, r);
}
public static long merge(int[] arr, int l, int mid, int r)
{
int i = l, j = mid + 1, idx = 0;
long ans = 0;
int[] temp = new int[r - l + 1];
while (i <= mid && j <= r)
{
if (arr[i] <= arr[j])
{
ans += arr[i] * (r - j + 1);
temp[idx++] = arr[i++];
}
else
temp[idx++] = arr[j++];
}
while (i <= mid)
temp[idx++] = arr[i++];
while (j <= r)
temp[idx++] = arr[j++];
System.arraycopy(temp, 0, arr, l, r - l + 1);
return ans;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
System.out.println(solution(arr));
}
}
CD23 自然数数组的排序
/* 模拟 */
public class CD23_1
{
public static int[] solution(int[] arr)
{
for (int i = 0; i < arr.length; i++)
{
if (arr[i] == i + 1) continue;
int temp = arr[arr[i] - 1];
arr[arr[i] - 1] = arr[i];
arr[i] = temp;
i--;
}
return arr;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
int[] res = solution(arr);
System.out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}
}
CD24 奇数下标都是奇数或者偶数下标都是偶数
public class CD24_1
{
public static int[] solution(int[] arr)
{
int even = 0, odd = 1, idx = arr.length - 1;
while (even <= idx && odd <= idx)
{
if (arr[idx] % 2 == 0)
{
swap(arr, idx, even);
even += 2;
}
else
{
swap(arr, idx, odd);
odd += 2;
}
}
return arr;
}
public static void swap(int[] arr, int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = in.nextInt();
int[] res = solution(arr);
System.out.println(Arrays.stream(res).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}
}